skip to Main Content

A Producer hasOne Distillery, a Distillery belongsToMany Whiskies.

A Whisky belongsToMany Distillery, a Distillery belongsTo Producer.

I wish to use hasManyThrough so, to get a Producer‘s Whiskies that belongToMany Distillery.

But how can I use hasManyThrough with belongsToMany relationship? I am aware you can specify the join keys, and I think you may be able to muck about with the pivot table, but I can’t figure it out.

2

Answers


  1. I think that you relationships shoul look like this:

    // Producer model
    public function distillery()
    {
        return $this->hasOne(Distillery::class);
    }
    
    // Distillery model
    public function producer()
    {
        return $this->belongsTo(Producer::class);
    }
    
    public function whiskies()
    {
        return $this->belongsToMany(Whisky::class);
    }
    
    // Whisky model
    public function distilleries()
    {
        return $this->belongsToMany(Distillery::class);
    }
    

    To get the whiskies of a producer through a distillery, you can’t use hasManyThrough directly. Instead, you can define a custom method:

    // In the Producer model
    
    public function whiskies()
    {
        $distillery = $this->distillery;
    
        if($distillery) {
            return $distillery->whiskies;
        }
    
        return collect(); // empty collection if no distillery
    }
    
    Login or Signup to reply.
  2. Unfortunately, hasManyThrough does not directly support your scenario.

    However, you can achieve your goal by manually defining a custom method in your Producer model to retrieve the whiskies through distilleries.

    class Producer extends Model
    {
        public function whiskies()
        {
            return Whisky::whereHas('distilleries', function ($query) {
                $query->where('producer_id', $this->id);
            });
        }
    }
    

    Also define the inverse relationship in your Whisky model to get the producer

    class Whisky extends Model
    {
        public function producer()
        {
            return $this->belongsTo(Producer::class, 'producer_id');
        }
    }
    

    Now you can retrieve a producer’s whiskies like this:

    $producer = Producer::find($producerId);
    $whiskies = $producer->whiskies;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search