Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincej's avatar
Level 15

Can't get Many-to-Many to work

HI All!

I am new to Eloquent relationships having done everything in the past the old school way with SQL. However, I am failing to get my pivot table to work having spent 2 afternoons trying. I must be doing something wrong. My three tables are:

customer PK and ID is 'id'

quotations PK and ID is 'reference'. eg abc1234. this table also contains a customer_id

products PK and ID is 'product_id' eg 1234

product_quoation FK is product_id and reference

Using relationships I can get a quotation and a product, but I can not get the products related to a quotation or the inverse, a quotation related to a product. Obviously there is something wrong with the relationship and / or the pivot table.

So, inside the Quotation model I have this:

public function products(){
        return $this->belongsToMany(Product::class, 'product_quotations', 'reference', 'product_id');
    }

Inside Tinker I will run :

$quote = App\Models\Quotation::first();

I get the first quote with the reference number.

then:

$quote->product
= null

I have quadruple checked the obvious: there is a product_id which matches the quote. There is a product_id and a reference in both product and quotation table and the product_quotation table.

Any ideas?

0 likes
4 replies
LaryAI's avatar
Level 58

It seems like you're on the right track with setting up a many-to-many relationship using Eloquent. However, there might be a small issue with the way you've defined the relationship in your Quotation model. Let's go through the steps to ensure everything is set up correctly.

First, ensure that your pivot table product_quotation has the correct foreign key column names that match the primary keys in the related tables. Based on your description, the pivot table should have product_id and reference as foreign keys.

Next, let's define the relationships in both the Product and Quotation models. Since you've mentioned custom primary keys, you'll need to specify these keys in the relationship methods.

Here's how you should define the relationship in your Quotation model:

class Quotation extends Model
{
    // If your primary key is not 'id', specify it here
    protected $primaryKey = 'reference';

    public function products()
    {
        // Assuming 'product_quotations' is the pivot table name
        // 'reference' is the foreign key name in the pivot table for the Quotation model
        // 'product_id' is the foreign key name in the pivot table for the Product model
        return $this->belongsToMany(Product::class, 'product_quotations', 'reference', 'product_id');
    }
}

And here's how you should define the inverse relationship in your Product model:

class Product extends Model
{
    // If your primary key is not 'id', specify it here
    protected $primaryKey = 'product_id';

    public function quotations()
    {
        // The order of keys is the inverse of the Quotation model
        return $this->belongsToMany(Quotation::class, 'product_quotations', 'product_id', 'reference');
    }
}

Now, when you want to retrieve the products related to a quotation, you should use the relationship method you've defined (products), not product. Here's how you can do it in Tinker:

$quote = App\Models\Quotation::first();
$products = $quote->products; // Use the relationship method 'products', not 'product'

If you still encounter issues, make sure that:

  1. The product_quotations pivot table contains the correct data with matching product_id and reference values.
  2. The Product and Quotation models are in the correct namespace if you're using namespaces.
  3. You've run composer dump-autoload if you've made changes to the class names or locations to ensure the autoloader is up to date.

If you've checked all of these and it's still not working, please provide more details about the error messages or unexpected behavior you're encountering.

gych's avatar
gych
Best Answer
Level 29

In the Quotation model you defined the method as products() but you are using $quote->product. You should use $quote->products instead.

vincej's avatar
Level 15

@gych Good catch. I thought a person had to reference the model 'Product' rather than the function 'products'

gych's avatar

@vincej This is because the Product model can have multiple relations defined. By defining and calling these methods, Laravel knows which relation to use. If you had to reference the model 'Product' without specifying the relation method Laravel won't know which relationship to work with.

Please or to participate in this conversation.