Rob W
Rob W

Reputation: 9142

Laravel 5.2 hasManyThrough relationship issue

I have 3 tables: orders, codes, events

I want to be able to pull all events that an order has, but there's an intermediary table that acts as a pivot table. I've been trying to use hasManyThrough and belongsToMany (along with withPivot) without any luck.

Examples:

public function events()
{
    return $this->belongsToMany('events'); // tried this, fails
    return $this->hasManyThrough('events', 'codes'); // tried this, fails
    return $this->hasManyThrough('events', 'codes', 'event_id', 'id'); // tried this, fails
}

Any pointers would be great!

example image

Upvotes: 1

Views: 730

Answers (2)

Janaka R Rajapaksha
Janaka R Rajapaksha

Reputation: 3744

There are many ways to do this. I will show a one you can get it done.

In Order.php model

public function codes(){
   return $this->has('App\Http\Code');
}

In Code.php model

public function orders(){
   return $this->belongsTo('App\Http\Order');
}

public function events(){
   return $this->hasMany('App\Http\Event');
}

In Event.php model

public function codes(){
   return $this->belongsTo('App\Http\Code');
}

Then in you Controller, call them to get required data.

In your case you can do it like below:

$orders = Order::with(['codes' => function($q){
    $q->with('events');
})->get();

May be you can get them with nested manner(not sure about this because i didn't tried before posting):

$orders = Order::with('codes.events')->get();

put return $orders; in your controller to see the query.

Enjoy!

Upvotes: 0

patricus
patricus

Reputation: 62228

That's a belongsToMany setup. First, the first parameter is the name of the related class. Second, since your pivot table doesn't follow the Laravel naming conventions, you need to specify the name of the pivot table in your relationship definition:

public function events()
{
    // first parameter is the name of the related class
    // second parameter is pivot table name
    return $this->belongsToMany(Event::class, 'codes');
}

With this setup, you can do:

// get an order
$order = Order::first();

// has all the events related to an order
$events = $order->events;

Upvotes: 3

Related Questions