Laravel Polymorphic Many to Many relationship

时间:2018-12-03 12:53:10

标签: laravel polymorphism

I am very new to polymorphic relationships and am struggling on my first task. My real life scenario is complicated, so for the purpose of this question, I have simplified it a little.

I have a range of products. Each of these products can be 'tagged' to one or more "Categories", "Brand" and "Consumer". For example:

enter image description here

I figured with this setup, I would need a table for my polymorphic relationships as below:

enter image description here

I have created a new Taggable class which contains the following

<?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Model;

    class Taggable extends Model
    {
        public function taggable()
        {
            return $this->morphTo();
        }
    }

...and added a method to my Product class:

public function taggedCategories()
{
    return $this->morphMany(Taggable::class, 'taggable');
} 

Finally, in my ProductController, I am trying to retrieve all products with their relationships as such:

$products = Product::with('taggedCategories')

Whilst this isn't producing an error, there are no categories returned in my results. Looking at the SQL output in LaravelDebugBar, I see the following SQL.

select * from `taggables` where `taggables`.`taggable_id` in (1) and `taggables`.`taggable_type` = 'App\Models\Product'

This clearly is not right, but I cannot for love nor money figure out where I have gone wrong. I feel I am close, but not quite there.

Can anyone explain what is wrong? Also, would I need to do something different for getting the "Brand" as this is a one-to-many relationship, not many-to-many?

Thanks

1 个答案:

答案 0 :(得分:0)

您的模型的结构将如下所示:

class Categories extends Model
{        
    public function products()
    {
        return $this->morphToMany('App\Tag', 'productable');
    }
}

class Brand extends Model
{        
    public function products()
    {
        return $this->morphToMany('App\Tag', 'productable');
    }
}

//和消费者,....

用户模型:

class Product extends Model
{        
    public function categories()
    {
        return $this->morphedByMany('App\Categories', 'productable');
    }

    public function brands()
    {
        return $this->morphedByMany('App\Brunds', 'productable');
    }
}

数据库架构:

categories
    id - integer
    ...

brands
    id - integer
    ...

consumer
    id - integer
    ...

productable
    product_id - integer
    productable_id - integer
    productable_type - string

现在,您可以检索关系:

$categories = App\Categories::find(1);
// retrieve product of a type
foreach ($categories->products as $product) {
    //
}


$product = App\Product::find(1);
// retrvieve categories  of a product
foreach ($product->categories as $categories) {
    //
}

实际上,您的类型产品(类别,品牌,消费者)是可以生产的。