Reputation: 1806
I have existing data to work with: I got a table that contains all sportevents called sportevents
.
id ....
name ....
....
These sportevents have a pivot table that define relations to the "same" sportevent happened in the previous year and the one of next year. Bit confusing design, but here is the table called eventrelations: I try to explain with years 2018 and 2019
id ....
event1: sportevent_id of 2019 event
event2: sportevent_id or 2018 event
....
My approach would be to create a Model called Eventrelation
with the following relations:
public function previous(){
return $this->belongsTo('App\Sportevent','event1','id' );
}
public function next(){
return $this->belongsTo('App\Sportevent','event2','id' );
}
and in my Sportevent
Model I would do the following:
public function previousEvent(){
return $this->hasOne('App\Eventrelation','event2','id' );
}
public function nextEvent(){
return $this->hasOne('App\Eventrelation','event1','id');
}
Although this is gonna work, I don't think this is the proper way to do it. I have setup other relations with a pivot table, but this one seems to be a bit more tricky considering the existing data structure and the relationship to the same Model. Any advice would be much appreciated.
UPDATE
I made it work the way I proposed above, the reason why I would rather have a cleaner version is to reduce the code (that's part of being cleaner :-)). So here is how I call these relations and how I would rather call them:
$previousEvent = $thisEvent->previousEvent ? $thisEvent->previousEvent->previous : null;
$nextEvent = $thisEvent->nextEvent ? $thisEvent->nextEvent->next : null;
// Better would be:
$previousEvent = $thisEvent->previousEvent;
$nextEvent = $thisEvent->nextEvent;
Upvotes: 0
Views: 116
Reputation: 1806
Here is the full solution (Not needing the Pivot table at all)
I added 2 fields to my sportsevents table
previous_sportevent_id int(11) Null
next_sportevent_id int(11) Null
I then migrated the data of the eventrelations table to the new columns
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
In the Sportevent model I changed the relations:
public function previousEvent(){
return $this->hasOne('App\Sportevent','id','previous_sportevent_id' );
}
public function nextEvent(){
return $this->hasOne('App\Sportevent','id','next_sportevent_id');
}
I can now use the new relations properly and clean in my Resource
return [
'id' => $this->id,
......
'nextEvent' => $this->nextEvent,
'previousEvent' => $this->previousEvent,
];
The Model Eventrelation and table eventrelations now can be deleted. I hope this will help someone...
Upvotes: 1
Reputation: 739
you do not need a pivot model at all. you can make a relationship with a class itself.
in your sportsevent model:
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');
}
if there is only one event, you can add a term ->first()
to the end of relationships.
BUT, you can also simply add two columns, 2018_event and 2019_event and add the ids of events there, and then use hasOne relationship. your call
Upvotes: 0