Self-relationship with Eloquent in Laravel 5:3

Asked

Viewed 584 times

2

I am building an immigrant control application and I own an imigrants table that has 3 self relationships. Its structure is as follows.

  • id -> pk
  • first_name -> varchar
  • last_name -> varchar
  • (...)
  • Father -> integer (fk)
  • Mother -> integer (fk)
  • spouse -> integer (fk)

But I’m not being able to determine the correct relationship with eloquent (I’m still learning how to use Latin). I have tested with hasOne, belongsTo etc. and can not make correctly associate. Using for example the query:

$imigrant->father()->save($father)

It is added to $imigrant id in $Father. Contrary to what I wish. And if I use belongsTo() with associate(), ex:

$imigrant->father()->associate($father)

It arrow null in the id of $imigrant and merge $Father into type:

App\Imigrant {#680
 id: null,
 first_name: "FName",
 last_name: "LName",
 birth_place: null,
 birth_date: null,
 disembark_place: null,
 disembark_date: null,
 father: App\Imigrant {#676
   id: 1,
   first_name: "FName2",
   last_name: "LName2",
   birth_place: null,
   birth_date: null,
   disembark_place: null,
   disembark_date: null,
   father: null,
   mother: null,
   spouse: null,
   ship: null,
   created_at: "2016-12-26 14:59:17",
   updated_at: "2016-12-26 14:59:17",
 },
 mother: null,
 spouse: null,
 ship: null,
 created_at: "2016-12-26 15:12:16",
 updated_at: "2016-12-26 15:12:16",

And does not update the database.

I know I could make the manual association, but I wanted to use the resources of Ager query that associates the data and automatically pulls the associations in the search. If only someone could shed some light on how I could make the Model association work. Otherwise I’ll just have to do it on the nail. : D

  • Because man, I understand the name of the column in the bank is outside the standard that the Standard waits, so you’ll have to specify it in the relation, try so: return $this->belongsTo('ModelDestino', 'father'); Fountain

  • @Juniornunes Cara, I broke my head here and I think I’ve solved the case. I had determined the correct field, otherwise he would give Exception no save and such pq n would find the correct column. But as I was testing with hasOne, it wasn’t working and the relationship was going backwards. I changed to belongsTo and it’s working now, just use a belongsTo for every fk, now I can continue to develop the rest and find something else to break the head kkk

  • @Juniornunes actually I don’t even know why it worked, I had tested it before and I had taken it, but it may have been my mistake to forget to restart Tinker to update the references.

  • I’ve already lost enough time to forget to restart Tinker kkk, I’m glad you solved, put an answer and mark as solved to help people who have the same problem!

  • A tip for you to connect when using belongsTo or hasOne is as follows: The belongsTo, is when the reference key is in the model that you are moving, example: I am in User and I have a field called group_id, so I have a belongsTo for groups, hasOne, will always give you the possibility to also be hasMany, for this reason the key must be in the other table, because following the previous example a user could not have many groups, you know? Example of hasOne: Table users hasOne for table logs (logs have a user_id)

  • @Israelmerljak for each member can have one parent only father and a father can several immigrants?

  • @Virgilionovic yes, a Father, a Mother and a spouse for each immigrant. enables a Father to have several "children" and a tbm Mother. I still have q check the case of the spouse q has q be 1-1. but that think q would be just I relate both tables in the association. The problem of the question already solved, I will mark as ok. Thanks for the answers of all.

Show 2 more comments

1 answer

2


After breaking my head enough I decided. Besides I forgot to restart Tinker (my changes were not reflecting). The correct association for my case was $this->belongsTo() because FK is local (this on the same table).

Thanks for the answers, they helped a lot :D

Here’s how the Model worked (at first):

class Imigrant extends Model
{
    protected $genders = [
        "m" => "masculino",
        "f" => "feminino"
    ];

    protected $fillable = [
        "first_name",
        "last_name",
        "gender"
    ];

    protected $dates = [
        "created_at",
        "updated_at",
        "birth_date",
        "disembard_date"
    ];

    public function father()
    {
        return $this->belongsTo("App\Imigrant", "father_id");
    }

    public function mother()
    {
        return $this->belongsTo("App\Imigrant", "mother_id");
    }

    public function spouse()
    {
        return $this->belongsTo("App\Imigrant", "spouse_id");
    }

    public function documents()
    {
        return $this->hasMany("App\Document");
    }

    public function contributions()
    {
        return $this->hasMany("App\Contribution");
    }

    public function children()
    {
        return $this->hasMany("App\Imigrant")->where("father_id", $this->id);
    }

    public function associateFather(Imigrant $father)
    {
        $r = $father->save();
        $this->father()->associate($father);
        return $this->save() == $r;
    }

    public function associateMother(Imigrant $mother)
    {
        $r = $mother->save();
        $this->mother()->associate($mother);
        return $this->save() == $r;
    }

    public function associateSpouse(Imigrant $spouse)
    {
        $spouse->spouse_id = $this->id;
        $r = $spouse->save();
        $this->spouse()->associate($spouse);
        return $this->save() == $r;
    }

    public function getGenderAttribute($value)
    {
        if ($this->gender == "Masculino") {
            return $this->hasMany("App\Imigrant", "father_id");
        } else {
            return $this->hasMany("App\Imigrant", "mother_id");
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.