首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在未指定id的情况下将hasOne模型附加到另一个Laravel/雄辩模型

在未指定id的情况下将hasOne模型附加到另一个Laravel/雄辩模型
EN

Stack Overflow用户
提问于 2014-10-03 11:20:47
回答 2查看 26.1K关注 0票数 17

背景

假设我们有以下两个表,其中type_id引用questionType中的一行

问题

代码语言:javascript
复制
id | type_id | description
---+---------+------------
1  | 1       | A nice question
.. | ..      | ..

questionType

代码语言:javascript
复制
id | name 
---+----------------
1  | Multiple-choice 
.. | ..

有以下雄辩的模型:

代码语言:javascript
复制
class Question extends Model {
    public function type() {
        return $this->hasOne( 'QuestionType', 'id', 'type_id' );
    }
}

class QuestionType extends Model {
}

问题1

如何添加引用现有问题类型的新问题,而无需使用ids手动执行任何操作?例如,以下工作很难看,海事组织,因为我必须手动分配相应的问题类型id:

代码语言:javascript
复制
$q = new Question;
$q->type_id = 1; // Multiple-choice
$q->description = 'This is a multiple-choice question';
$q->save();

人们可能会认为,有一种方法可以让ORM处理id分配(难道避免使用ORMs这样的东西不重要吗?),类似于(这在雄辩的ORM中是行不通的):

代码语言:javascript
复制
$q = new Question;
$q->type = QuestionType.where('name', '=', 'Multiple-choice');
$q->description = 'This is a multiple-choice question';
$q->save();

问题2

关于问题1,我应该如何添加一个引用新问题类型的新问题,而不用手动处理ids呢?同样,我也设想了这样一种情况:

代码语言:javascript
复制
$t = new QuestionType;
$t->name = 'Another type';

$q = new Question;
$q->type = $t;
$q->description = 'This is a multiple-choice question';
$q->save();

在这里,我希望$q->save()同时保存新的问题类型和问题(或类似的内容)。

以下是工作,但我再次指定了自己的id,我认为ORM应该处理这个id:

代码语言:javascript
复制
$t = new QuestionType;
$t->name = 'Another type';
$t->save();

$q = new Question;
$q->type = $t->id;
$q->description = 'This is a multiple-choice question';
$q->save();

我尝试过使用不同的save()update()方法组合,但没有成功。我还寻找attach(),它存在于hasMany关系中,但似乎在hasOne中缺失。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-03 11:33:01

首先,你误解了你所指的关系。

以下是你所需要的:

代码语言:javascript
复制
// Question model
public function questionType()
{
  return $this->belongsTo('QuestionType', 'type_id');
}

// QuestionType model
public function questions()
{
  return $this->hasMany('Question', 'type_id');
}

然后你可以像这样把它们连接在一起:

代码语言:javascript
复制
$questionType = QuestionType::where(..)->first();

$question = new Question;
... // do something with it

// associate
$question->questionType()->associate($questionType);

// or the other way around - save new question and link to the type:
$questionType->questions()->save($question);

您也可以显式传递一个id来关联:

代码语言:javascript
复制
$question->type_id = $someTypeId;
$question->save();

你不能这么做:

代码语言:javascript
复制
$question->questionType = $someQuestionType;

对于这种方式,雄辩处理模型属性,而不是关系。

问题2

代码语言:javascript
复制
$questionType = new QuestionType(['name' => 'multiple']);
$questionType->save();

$question = new Question([ ... some values ... ]);

// then either this way:
$questionType->questions()->save($question);

// or, again, the other way around:
$question->questionType()->associate($questionType);
$question->save();
票数 23
EN

Stack Overflow用户

发布于 2014-10-03 11:24:45

回答问题1对我来说,两种方法都很好,你不需要改变任何东西。

回答问题2,你应该照你说的做。除非您使用手动的QuestionType方法,否则ORM不会自动创建save

例如,如果您使用了代码:

代码语言:javascript
复制
$t = new QuestionType;
$t->name = 'Another type';

$t2 = new QuestionType;
$t2->name = 'Another type 2';

$q = new Question;
$q->type = $t; // what here - $t2 or $t ?
$q->description = 'This is a multiple-choice question';
$q->save();

ORM应该做什么决定?问题与任何$t$t2都没有关联,因此ORM不会为您决定。你得告诉ORM这是什么类型。

我不是一个ORM /雄辩的专家,但我认为你对ORM期望过高。奥姆不应该猜你想做什么。它帮助您管理关系或对象,但如果您不让它这样做,它就不会关联对象。

不过,您可以尝试使用mutator。您可以在您的问题模型中添加:

代码语言:javascript
复制
public function setTypeAttribute($value)
{
    $value->save();
    $this->attributes['type_id'] = $value->id
}

现在应该可以使用$q->type = $t;了(但是我还没有测试它)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26178049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档