0
votes

I have a problem I haven't been able to solve in days. Maybe there is someone here who can help me.

Basic idea

I have a model named Product. Each Product can have multiple ProductAttributes (belongsToMany with pivot).

Example:

Product: Car

  • ProductAttributes:
    • Color
    • HORSEPOWER

The pivot table for ProductAttribute holds the values for the respective attributes (color = blue, PS = 180).

This already works very well.

Problem

Now I want to implement product packages. A product package (ProductBundle) has many products. But these products should have their own pivot tables for their attributes. So in a product bundle I want to be able to specify that the car I created has more PS than defined in the actual product.

For this I need 2 pivot tables for the attributes.

What I've already tried

  • ProductBundle belongsToMany Product using a different pivot-table
  • ProductBundle belongsToMany ProductBundleProduct (ProductBundleProduct has a field called product_id which refers to the actual "basic product")

In both scenarios I have the problem that the pivot table for the attributes of the product belonging to a product bundle is not saved correctly:

Product

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function productBundleAttributes()
    {   
        return $this->belongsToMany(ProductAttribute::class,
            product_bundle_product_attribute')
            ->withPivot($this->attributefields)-> withTimestamps();

    }

controller

$prod = Product::findOrFail($product['id']);

$added = $productbundle->products()->save($prod, [
    'custom' => $product['custom'],
    'title' => $product['title'],
    # 'factor' => $product['factor']
]);

/*Save attributes*/
$added->syncProductBundleAttributes($product['attributes']],
    $productbundle->id);

sync method

    public function syncProductBundleAttributes(
        array $attributes,
        int $id
    ) {
        $this->checkProductAttributesRecursively(collect($attributes)->transform(function (
            $attributes
        ) use (
            $id
        ) {
            $attribute['product_bundle_id'] = $id;
            $attribute['product_attribute_id'] = $attribute['id'];

            return $attribute;
        })->toArray());

        $this->productBundleAttributes()->attach($this->result);

        return $this->result;
    }

Unfortunately, this means that only one attribute is stored at a time.

1

1 Answers

0
votes

You can have an additional column in the pivot table between Product and ProductAttributes, say product_bundle_id. So this way you can get attributes for specific bundle, or basic attributes with product_bundle_id as 0

Look at Saving Additional Data On A Pivot Table in Laravel Eloquent, Many to Many