我有一个带有id(主键)的component_events表,一个event_id和一个event_type(字符串)。
我想确保如果调用了错误的关系,它就不会返回错误的记录。
我唯一能想到的是(在ComponentEvent模型中)......
public function AircraftEvent()
{
return ($this->event_type === 'flight') ? $this->belongsTo('AircraftFlightEvent', 'event_id') : $this->belongsTo('AircraftMaintenanceEvent', 'event_id');
}
必须有更好的方法!
我看过多态关系的文档,但我不理解它,它似乎是一个“很多”的关系,在我的情况下它不是。
我宁愿有两个不同的关系......
public function AircraftFlightEvent()
{
return $this->belongsTo('AircraftFlightEvent', 'event_id');
}
public function AircraftMaintenanceEvent()
{
return $this->belongsTo('AircraftMaintenanceEvent', 'event_id');
}
但如果有人不小心打错了关系,可能会返回错误的记录。
我尝试添加 - > where('flight',$ this-> event_type),但是会查看相关表中的列而不是component_events表。
我也尝试过范围,但是Laravel似乎不喜欢附属于belongsTo关系的范围。
任何帮助都将不胜感激。
更新
我发现如果我使用多对多的多态关系,我可以得到正确的结果和查询。唯一的问题是ComponentEvent实际上只有一个相关的AircraftFlightEvent或AircraftMaintenanceEvent(取决于component_events.event_type的值)。
AppServiceProvider:
public function boot()
{
Relation::morphMap([
'flight' => \AircraftFlightEvent::class,
'maintenance' => \AircraftMaintenanceEvent::class,
]);
}
AircraftFlightEvent和AircraftMaintenanceEvent:
public function ComponentEvents()
{
return $this->morphMany('ComponentEvent', 'event');
}
ComponentEvent:
public function AircraftFlightEvent()
{
return $this->morphedByMany('AircraftFlightEvent', 'event', 'component_events', 'id', 'event_id');
}
public function AircraftMaintenanceEvent()
{
return $this->morphedByMany('AircraftMaintenanceEvent', 'event', 'component_events', 'id', 'event_id');
}
唯一的问题是,当调用$ component_event-> AircraftFlightEvent(或维护)时,它会返回一个包含单个实例的集合。我只需要单个实例,而不是集合,因为它始终只是一个模型。
我尝试过使用morphOne,但它不会生成正确的SQL。它认为event_type是对面表格中的一列。它根本不包括对component_events.event_type值的检查。
如果最终我不得不忍住它返回一个包含一个对象的集合,那很好......但是如果我能做得正确的话,它首先会破坏定义多态关系的大部分目的。< / p>
答案 0 :(得分:1)
我认为这是多态关系的一个很好的原因。但正如您所提到的,Laravel文档可以帮助您返回许多记录,而您只需要匹配一条记录,而Laravel社区自然已经想到了这一点。有一种关系,这种关系未在名为morphOne
的区域Laravel文档中涵盖,可在Laravel Api Documentation中找到。
要实现此关系,您的ComponentEvent
模型应具有如下函数:
public function event()
{
return $this->morphTo();
}
您的AircraftFlightEvent
和AircraftMaintenanceEvent
模型都应具有:
public function event()
{
return $this->morphOne(\App\ComponentEvent::class, 'event');
}
(如果您愿意,可以将其提取到特征中)
请注意,morphOne
关系中的第二个参数用于匹配component_event
表的列前缀。因此,当使用'event'
时,Laravel会在表格中查找event_id
和event_type
列。
现在,如果您有一个$componentEvent
,则只需致电$componentEvent->event()
即可获得AircraftFlightEvent
或AircraftMaintenanceEvent
型号的单个实例,而不是集合
希望这会有所帮助。快乐的编码。