Laravel条件属于

时间:2016-10-17 23:23:53

标签: laravel polymorphism

我有一个带有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>

1 个答案:

答案 0 :(得分:1)

我认为这是多态关系的一个很好的原因。但正如您所提到的,Laravel文档可以帮助您返回许多记录,而您只需要匹配一条记录,而Laravel社区自然已经想到了这一点。有一种关系,这种关系未在名为morphOne的区域Laravel文档中涵盖,可在Laravel Api Documentation中找到。

要实现此关系,您的ComponentEvent模型应具有如下函数:

 public function event()
 {
    return $this->morphTo();
 }

您的AircraftFlightEventAircraftMaintenanceEvent模型都应具有:

public function event()
{
    return $this->morphOne(\App\ComponentEvent::class, 'event');
}

(如果您愿意,可以将其提取到特征中)

请注意,morphOne关系中的第二个参数用于匹配component_event表的列前缀。因此,当使用'event'时,Laravel会在表格中查找event_idevent_type列。

现在,如果您有一个$componentEvent,则只需致电$componentEvent->event()即可获得AircraftFlightEventAircraftMaintenanceEvent型号的单个实例,而不是集合

希望这会有所帮助。快乐的编码。