Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel hasManyThrough equivalent: belongsTo relationship through another model

I've got a model, it belongs to another model, that model belongs to a third model, and I want an eloquent method to relate the first model to the third one.

There doesn't appear to be a belongsToThrough (or hasOneThrough) method, though. I've already tried chaining multiple belongsTo methods, but that hasn't worked (Call to undefined method Illuminate\Database\Query\Builder::belongsTo()). Any ideas?

Here is an example of the models:

// The first model
// Schema: this model has a middle_id column in the database
class Origin extends Eloquent {
    public function middle()
    {
        return $this->belongsTo('Middle');
    }
}

// The second model
// Schema: this model has a target_id column in the database, but NOT an origin_id column
class Middle extends Eloquent {
    public function target()
    {
        return $this->belongsTo('Target');
    }
}

// The third model
class Target extends Eloquent {
}

What I'd like to do is add something like the following method to the Origin model:

// A relationship method on the first "origin" model
public function target()
{
    // First argument is the target model, second argument is the middle "through" model, third argument is the database column in middle model that it uses to find the target model, or soemthing
    return $this->hasOneThrough('Target', 'Middle', 'target_id');
}

So that I can use $originInstance->target->title, etc.

like image 390
BenjaminRH Avatar asked Apr 29 '14 13:04

BenjaminRH


1 Answers

You can use hasOneThrough but you need to customize keys.

public function parent()
{
    return $this->hasOneThrough(Parent::class, Middle::class, 'id', 'id', 'middle_id', 'parent_id');
}

Origin belongs to Middle, and Middle belongs to Parent. Middle need has parent_id foreign key, and Origin has middle_id foreign key.

Finally you can use:

Origin::find(1)->parent;
like image 121
Marek Gralikowski Avatar answered Oct 23 '22 03:10

Marek Gralikowski