Laravel 5 多态关系
Laravel 5 Polymorphic Relationship
目前还不完全清楚,因为这将是我第一次对此进行修补。我的table结构如下:
questions
- id
- type_id
multiple_choice_options
- id
- question_id
drag_and_drop_options
- id
- question_id
questions
table 上的 type_id
字段决定从哪些选项 table 加载。所以基本上我想在 Question
模型上建立如下关系:
class Question extends Model {
public function options() {
// not sure what to return here?
}
}
对于期权模型,这是正确的逆定义吗?
class MultipleChoiceOption extends Model {
public function question() {
return $this->belongsTo(Question::class);
}
}
class DragAndDropOptions extends Model {
public function question() {
return $this->belongsTo(Question::class);
}
}
如何设置它以处理多态关系?
您可以简单地在 options()
关系中构建一个开关:
class Question extends Model {
public function options() {
if ($type_id === 'multiple') {
return $this->hasMany(MultipleChoiceOption::class);
} else {
return $this->hasMany(DragAndDropOptions::class);
}
}
}
请注意这些神奇的关系,您需要在您的应用中进行额外的类型检查和仔细的编码。
查看 Laravel Docs on Polymorphism,有一些函数可以利用稍微不同的数据结构,例如:
questions
- id
- optionable_id
- optionable_type
multiple_choice_options
- id
drag_and_drop_options
- id
型号:
class Question extends Model {
public function optionable() {
return $this->morphTo();
}
}
class MultipleChoiceOption extends Model {
public function question() {
return $this->morphMany('App\Question', 'optionable');
}
}
class DragAndDropOptions extends Model {
public function question() {
return $this->morphMany('App\Question', 'optionable');
}
}
请注意,optionable_type
列将包含所属模型的 class 名称。
旁注,你的数据结构关系逻辑对我来说似乎有点奇怪,但可能仍然服务于你正在尝试做的事情。我可能会使用模型 Question
、Option
、QuestionType
,以便选项独立于问题和问题类型。这将使您能够更改问题类型而无需更改选项。
考虑到您要实现的目标:
a)一个选项只能属于一个问题,
b)一个问题可以有多个选项,
我认为更简洁的解决方案可能涉及调整您的数据库设计,
questions
- id
- body
- question_type_id
question_type
- id
- name
options
- id
- name
- question_id
class question extends Model {
public function options() {
$this->hasMany('App\option','question_id')
}
}
class option extends Model {
public function question() {
return $this->belongsTo('App\question');
}
}
您的 question_type table 将包含 muiltiple_choice、拖放等,因此您无需使用 'if' 语句或 'switch',这让你的代码更简洁。您也不需要在添加新问题类型时编辑代码。
目前还不完全清楚,因为这将是我第一次对此进行修补。我的table结构如下:
questions
- id
- type_id
multiple_choice_options
- id
- question_id
drag_and_drop_options
- id
- question_id
questions
table 上的 type_id
字段决定从哪些选项 table 加载。所以基本上我想在 Question
模型上建立如下关系:
class Question extends Model {
public function options() {
// not sure what to return here?
}
}
对于期权模型,这是正确的逆定义吗?
class MultipleChoiceOption extends Model {
public function question() {
return $this->belongsTo(Question::class);
}
}
class DragAndDropOptions extends Model {
public function question() {
return $this->belongsTo(Question::class);
}
}
如何设置它以处理多态关系?
您可以简单地在 options()
关系中构建一个开关:
class Question extends Model {
public function options() {
if ($type_id === 'multiple') {
return $this->hasMany(MultipleChoiceOption::class);
} else {
return $this->hasMany(DragAndDropOptions::class);
}
}
}
请注意这些神奇的关系,您需要在您的应用中进行额外的类型检查和仔细的编码。
查看 Laravel Docs on Polymorphism,有一些函数可以利用稍微不同的数据结构,例如:
questions
- id
- optionable_id
- optionable_type
multiple_choice_options
- id
drag_and_drop_options
- id
型号:
class Question extends Model {
public function optionable() {
return $this->morphTo();
}
}
class MultipleChoiceOption extends Model {
public function question() {
return $this->morphMany('App\Question', 'optionable');
}
}
class DragAndDropOptions extends Model {
public function question() {
return $this->morphMany('App\Question', 'optionable');
}
}
请注意,optionable_type
列将包含所属模型的 class 名称。
旁注,你的数据结构关系逻辑对我来说似乎有点奇怪,但可能仍然服务于你正在尝试做的事情。我可能会使用模型 Question
、Option
、QuestionType
,以便选项独立于问题和问题类型。这将使您能够更改问题类型而无需更改选项。
考虑到您要实现的目标:
a)一个选项只能属于一个问题,
b)一个问题可以有多个选项,
我认为更简洁的解决方案可能涉及调整您的数据库设计,
questions
- id
- body
- question_type_id
question_type
- id
- name
options
- id
- name
- question_id
class question extends Model {
public function options() {
$this->hasMany('App\option','question_id')
}
}
class option extends Model {
public function question() {
return $this->belongsTo('App\question');
}
}
您的 question_type table 将包含 muiltiple_choice、拖放等,因此您无需使用 'if' 语句或 'switch',这让你的代码更简洁。您也不需要在添加新问题类型时编辑代码。