我试图了解我在Laravel 5.3中的第一个多态关系。
我想要实现的关系是“编辑”和“编辑”。会有很多元素'每个元素都是自己的模型,并有一个订单。
例如,我将有一个' ElementText',' ElementImage',' ElementButton'模特然后编辑'编辑'将分配给它的各种元素。
这就是我认为我需要多态关系的原因。我不希望“编辑”中的每种元素类型都有多种关系。模特,我希望能够得到所有元素'无论其类型如何,都要按顺序排列。
我认为理念解决方案是拥有一个' editorial_element'带有
列的数据透视表editorial_id - integer
order - integer
element_id - integer
element_type - string
类似于laravel文档中的morphToMany
示例,但在该示例中,您需要指定要变形的模型。
所以我也想知道我是否应该在我的社论模型中使用morphTo()方法。
public function elements() {
return $this->morphTo();
}
但我认为这意味着我必须将_type
和_id
列添加到我的编辑表中,这些列将是向后的(每个编辑允许一个元素)
我是否可以设定我需要的关系,或者我接近错了?
答案 0 :(得分:1)
我不认为多态关系适合这里。我可能会这样接近它。
editorials
- id
- title
- etc...
elements
- editorial_id
- elements_id
- elements_type
elements_image
- id
- url
elements_text
- id
- text
然后你的模特可以。
class Editorial extends Model {
// ...
public function elements() {
return $this->hasMany(\Element::class);
}
// ...
}
class Element extends Model {
// ...
public function editorial() {
return $this->belongsTo(\Editorial::class);
}
public function image() {
return $this->belongsTo(\ElementImage::class, 'elements_id');
}
public function text() {
return $this->belongsTo(\ElementText::class, 'elements_id');
}
public function content() {
$type = $this->elements_type;
return $this->{$type}();
}
// ...
}
class ElementImage extends Model {
// ...
public function element() {
return $this->hasOne(\Element::class, 'elements_id');
}
// ...
}
class ElementText extends Model {
// ...
public function element() {
return $this->hasOne(\Element::class, 'elements_id');
}
// ...
}
也许那时你可以让所有元素实现一个强制所有元素都有render()
方法的接口,然后你可以在视图中执行此操作:
@foreach($editorial->elements as $element)
{{ $element->content->render() }}
@endforeach
然后,渲染方法可以负责格式化和输出内容。
这一切都只是理论,我有兴趣看看你是否可以让它发挥作用,因为它是我之前试图解决的一个问题。如果您认为我的想法很愚蠢,请告诉我任何更正。
答案 1 :(得分:0)
您应该按照以下方式设置您的关系。
在Editorial
模型中,您应该为每个Element*
模型提供方法。 E.g。
public function textElements() {
return $this->morphedByMany(ElementText::class, 'element');
}
public function buttonElements() {
return $this->morphedByMany(ElementButton::class, 'element');
}
在Element*
模型中,您应该使用以下方法来获取它变形的所有Editorials
。
public function editorials()
return $this->morphToMany(Editorial::class, 'element');
}
注意:使用多态关系存在一些值得注意的问题。最重要的是,您可以在数据库结构中获得一些简单性,但同时又会丢失外键约束。这意味着,如果删除Element*
,则需要删除其手动变形的任何Editorials
,而在正常的Many to Many
关系中,您可以设置外键约束并且RDBMS为您完成此任务。
注2:首先,我会尝试查看这些Element表是否可以统一到一个表中。如果他们能够使你的工作变得更容易。但是如果你必须使用很多Element表,我认为两种方式都可以。每个都有优点和缺点。你必须自己处理数据库一致性的许多关系表或多态关系,无论哪种方式,你都不能与$editorial->elements()
建立关系。