Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Database One-to-Many with two foreign key fields in Laravel

I have been trying to define some Database schema to use the laravel framework. I want to model a Football match. The first step I wanted to do is to define the Entity Relationship diagram, but I found this (which I thought would be quite trivial) to be confusing in some aspects.

First, the obvious approach is to say that a Match is related with two Teams, and a Team is related to any number of Matches. So, we would have a "Many to Many" relationship.

But the implementation of a many to many relation is to have two tables and an intermediate table to relate both entities. I think this would be too much, when I know that a Match will always have two Teams and simply having two columns (local_id and visitant_id) with foreign keys to the Teams table would be enough. Plus, I want to be able to do:

Match::find(1)->local() or Match::find(1)->visitant();

So, thinking on this I am implementing a "One to Many" relation, but with this I have another issue. To retrieve all the matches a Team has played I would like to do:

Team::find(1)->matches(); 

But I cannot do this because I can only specify one key column when defining the matches() method in eloquent (by default it would be team_id, but it should be visitant_id and local_id).

like image 260
Noel De Martin Avatar asked Mar 26 '13 20:03

Noel De Martin


1 Answers

After some more digging into the source code I found there is a way to actually keep my database schema as it is and achieve what I want (at least in Laravel 4). I posted my problem in github and Taylor Otwell (creator of the framework) gave me the correct answer: https://github.com/laravel/framework/issues/1272

Quoting him, it should be as easy as this:

class Team extends Eloquent  {
    public function allMatches()
    {
        return $this->hasMany('Match', 'visitant_id')->orWhere('local_id', $this->id);
    }
}

And then...

$team = Team::find(2);
$matches = $team->allMatches;
like image 134
Noel De Martin Avatar answered Oct 13 '22 09:10

Noel De Martin