Raff W
Raff W

Reputation: 188

Eloquent relationship in custom pivot table

I might be overcomplicating things, but here's relationship I'm trying to write in Eloquent (Laravel 5):

I have a list of products and price lists. Each product can have many price lists. This is easy to do, but here's another thing - for every product <> price list assignment I can have many prices based on quantity, so it's like:

productID: 1010
priceListId: 1

min quantity: 1 -> price 10.00
min quantity: 5 -> price 9.50
min quantity: 10 -> price 9.00

productID: 1010
priceListId: 2

min quantity: 1 -> price 15.00
min quantity: 40 -> price 14.00
min quantity: 90 -> price 12.00

I think I know how to create custom pivot table although I don't know how to use it. I followed this link now I'm not sure if my code is correct and how to use it.

At the moment I have:

Product model:

class Product extends Model {

    public function pricelists()
    {
        return $this->belongsToMany('PriceList');
    }

    public function newPivot(Model $parent, array $attributes, $table, $exists)
    {
        if ($parent instanceof PriceList)
        {
            return new ProductPricePivot($parent, $attributes, $table, $exists);
        }

        return parent::newPivot($parent, $attributes, $table, $exists);
    }

}

PriceList model:

class PriceList extends Model {

    public function products()
    {
        return $this->belongsToMany('Product');
    }

    public function newPivot(Model $parent, array $attributes, $table, $exists)
    {
        if ($parent instanceof Product)
        {
            return new ProductPricePivot($parent, $attributes, $table, $exists);
        }

        return parent::newPivot($parent, $attributes, $table, $exists);
    }
}

Pivot:

class ProductPricePivot extends Pivot {

    public function product()
    {
        return $this->belongsTo('Product');
    }

    public function pricelist()
    {
        return $this->belongsTo('PriceList');
    }

    public function prices()
    {
        return $this->hasMany('ProductPrice');
    }

}

Now ProductPrice extends Model again and is just a standard model without any additional methods.

Is this correct? If so, then following example from above, how can I add new quantity/price level to price list 1 on product 1010?

At the moment, when creating relationships, I'm doing:

$productID = 1010;
$priceListID = 1;

$priceList = PriceList::find($priceListID);
$priceList->products()->attach($productID);

$productToPriceList = $priceList->products()->find($productID);

And I'm lost here... I find this relationship, but how can I now attach next quantity <> price level to it?

Can someone please give an example of how to use such relationship or links to pages where I can find something more about it? And yes, I check Laravel documentation, and yes, I googled it as well.

Thank you!

Upvotes: 4

Views: 5146

Answers (1)

Nati Mask
Nati Mask

Reputation: 676

As you described the case, I see here two types of relationships:

  1. Many-to-Many relationship between Product & PriceList
  2. Many-to-One relationship between PriceList & ProductPrice (which holds the "min-quantity" and "price") values.

I'm assuming that you don't need the same price condition for many "price-list"s. Every list will have it's price conditions.

Many-to-one relationship doesn't require pivot table.

Follow this link, you'll find that laravel Eloquent system helps you much.

You need 4 tables: products, price_lists, product_prices, products_to_pricelists (the pivot)

the products_to_pricelists table look like that:

*====*============*===============*
| id | product_id | price_list_id |
*====*============*===============*

Now the models:

Products:

class Product extends Eloquent {

    protected $table = 'products';

    public function price_lists()
    {
        return $this->belongsToMany('PriceList', 'products_to_pricelists', 'price_list_id');
    }

}

Price lists:

class PriceList extends Eloquent {

    protected $table = 'price_lists';

    public function prices()
    {
        return $this->hasMany('ProductPrice');
    }

}

Prices:

class ProductPrice extends Eloquent {

    protected $table = 'product_prices';

}

Now it's easy:

$productID = 1010;
$list_id = 1;
$theProduct = Product::find( $productID );
$theProductPriceLists = $theProduct->price_lists; // Don't use parens
$theList = Product::find( $productID )->price_lists()->where('price_lists.id', $list_id)->first(); // Here you use parens
$theListPrices = $theList->prices; // Again no parens

Laravel just manage for you the pivot-connection!

Hope that's help

Upvotes: 4

Related Questions