雄辩的一对一关系

时间:2018-10-08 10:19:37

标签: laravel laravel-5 eloquent relationship

我有可用的数据:我有一个表,其中包含名为sportevents的所有sportevents。

id ....
name ....
....

这些Sportevent具有一个数据透视表,该表定义了与上一年和次年发生的“相同” SportEvent的关系。有点令人困惑的设计,但这是称为“事件关系”的表:我试图用2018年和2019年来解释

id ....
event1: sportevent_id of 2019 event
event2: sportevent_id or 2018 event
....

我的方法是创建一个具有以下关系的名为Eventrelation的模型:

public function previous(){
    return $this->belongsTo('App\Sportevent','event1','id' );
}

public function next(){
    return $this->belongsTo('App\Sportevent','event2','id' );
}

在我的Sportevent模型中,我将执行以下操作:

public function previousEvent(){
    return $this->hasOne('App\Eventrelation','event2','id' );
}

public function nextEvent(){
    return $this->hasOne('App\Eventrelation','event1','id');
}

尽管这会奏效,但我认为这不是正确的方法。我已经设置了与数据透视表的其他关系,但是考虑到现有数据结构和与同一Model的关系,这似乎有些棘手。 任何建议将不胜感激。

更新

我按照上面的建议进行工作,之所以我想要一个更干净的版本,是因为减少了代码(这是更干净的一部分:-)。因此,这里是我如何称呼这些关系以及我宁愿称其为:

    $previousEvent = $thisEvent->previousEvent ? $thisEvent->previousEvent->previous : null;
    $nextEvent = $thisEvent->nextEvent ? $thisEvent->nextEvent->next : null;

    // Better would be:
    $previousEvent = $thisEvent->previousEvent;
    $nextEvent = $thisEvent->nextEvent;

2 个答案:

答案 0 :(得分:1)

这是完整的解决方案(根本不需要数据透视表)

我在sportsevents表中添加了2个字段

previous_sportevent_id  int(11) Null    
next_sportevent_id  int(11) Null

然后我将eventrelations表的数据迁移到新列

UPDATE `sportevents`
INNER JOIN eventrelations ON eventrelations.event1 = sportevents.id
SET sportevents.previous_sportevent_id = eventrelations.event2

UPDATE `sportevents`
INNER JOIN eventrelations ON eventrelations.event2 = sportevents.id
SET sportevents.next_sportevent_id = eventrelations.event1

在Sportevent模型中,我更改了关系:

public function previousEvent(){
    return $this->hasOne('App\Sportevent','id','previous_sportevent_id' );
}

public function nextEvent(){
    return $this->hasOne('App\Sportevent','id','next_sportevent_id');
}

我现在可以正确使用新关系并清理我的资源

return [
      'id' => $this->id,
      ......
      'nextEvent' => $this->nextEvent,
      'previousEvent' => $this->previousEvent,
    ];

现在可以删除模型事件关系和表事件关系。我希望这会帮助某人...

答案 1 :(得分:0)

您根本不需要枢轴模型。您可以与类本身建立关系。

在运动赛事模型中:

public function previousEvent()
{
  return $this->belongsToMany(SportsEvent::class, 'pivot_table_name', 'event_1', 'id');
}

public function nextEvent()
{
  return $this->belongsToMany(SportsEvent::class, 'pivot_table_name', 'event_2', 'id');
}

如果只有一个事件,则可以在关系的末尾添加术语->first()

但是,您还可以简单地添加两列2018_event和2019_event并在其中添加事件ID,然后使用hasOne关系。你的电话