Andreas Hunter
Andreas Hunter

Reputation: 5004

How to create relationships for product dynamic attributes?

I have Product model which has attributes. In my case to each product can be set 3 type of attributes: size, color, material. For each attribute I've custom table with model:

Models:

  1. Size
  2. ProductSize
  3. Color
  4. ProductColor
  5. Material
  6. ProductMaterial

Now if I want to add a new attribute to products I must create again two new tables e.g:

  1. NewAttribute
  2. ProductNewAttibute

How I can solve this problem with creating dynamic attibutes table. Each attributes can have many values in my case. Which relationtions I must use and how many tables can solve this problem?

Upvotes: 2

Views: 1393

Answers (1)

julianstark999
julianstark999

Reputation: 3616

You could solve your Problem with 3 Tables by using a many to many Relationship with a pivot field.

attributes

| id | name     |
|----|----------|
| 1  | size     |
| 2  | color    |
| 3  | material |

attribute_values

| id | value    | attribute_id|
|----|----------|--------------|
| 1  | S        | 1            |
| 2  | M        | 1            |
| 3  | XL       | 1            |

product_has_attributes

| product_id | attribute_id | attribute_value_id |
|------------|--------------|--------------------|
| 1          | 1            | 1                  |
| 1          | 2            | x                  |
| 1          | 3            | x                  |

So your Product Model has a attributes relation

class Product extends Model
{
    public function attributes()
    {
        return $this->belongsToMany('App\Attribute')
            ->withPivot('attribute_value_id')
            ->using('App\ProductAttributes');
    }
}

and your Attribute Model has a products relation

class Attribute extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product')
            ->withPivot('value')
            ->using('App\ProductAttributes');
    }
}
class ProductAttribute extends Model
{
    public function value()
    {
        return $this->belongsToMany('App\AttributeValue');
    }
}
@foreach($products as $product)
    @foreach($product->attributes as $attribute)
        echo $attribute->name.' - '.$attribute->pivot->value->value
    @endforeach
@endforeach

https://laravel.com/docs/7.x/eloquent-relationships#many-to-many

Edit Search for a Product with Attribute equals Value (untested pseudo code)

Product::whereHas('attributes.value', function ($query) {
        $query->where('name', 'size')
            ->where('value.value', '');
    })
    ->get();

Upvotes: 1

Related Questions