Right relation for eloquent model

113 Views Asked by At

After several attempts, I can not make an eloquent "relations" work.

I created a database with MySQL Workbech which contains the following tables:

  • Actors
  • ActorData
  • Nationality

Their relationship image:

relationship

In PHP instead I have the following code (summary):

class ActorData extends Model
{
    protected $table = 'actordata';

    [..]

    public function nationality()
    {
        return $this->hasOne("App\Models\ActorData\Nationality");
    }
}

class Actor extends Model
{
    protected $table = 'actors';

    [..]

    public function actorData()
    {
        return $this->hasOne('App\Models\ActorData');
    }
}

My goal is, when i call "->nationality", i wish it takes the "nationality", but i recive "null" or errors about "keys" not found.

$actorData = \App\Models\Actor::find(1)->actorData()->first();
var_dump($actorData->nationality);

I understand that "hasOne" looks for the key in "nationality", but I wanted to make a simple "link". As another solution, so I could simply take the "Nationality_Id" and look for it in the "Nationality" table, but I think it's a wrong approach.

I hope I have been exhaustive, thanks for your cooperation.

( in order to "fix" i had to add "$actorData->nationality()->associate($nationality))

2

There are 2 best solutions below

6
On BEST ANSWER

enter image description here

You relationship should look something like the above.

Where actorData is a pivot table for the 2 other tables.

Your classes should look like this:

class Actors extends Model{
    public function nationality() {
        return $this->belongsToMany(Nationality::class);
    }
}

class Nationality extends Model {
    public function actors() {
        return $this->belongsToMany(Actors::class);
    }
}

You're basically looking at Many-to-Many. Where each actor can have many nationalities while at the same time each nationality can belong to many actors.

Normally laravel expects the pivot table to be named something like actor_nationality, but you can specify the table name:

return $this->belongsToMany(ModelClassGoesHere, 'PIVOT TABLE GOES HERE', 'FIRST TABLE ID', 'SECOND TABLE ID');
1
On

Why can't you put the nationality_id directly on the actors table since, they can only have one. Then your relationship on the Actor would be

public function nationality() {
    return $this->hasOne(Nationality::class);
}

Then you could do $actor->nationality;

Your nationality class would be...

class Nationality extends Model {
    public function actors() {
        return $this->hasMany(Actor::class);
    }
}