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

vnc00's avatar
Level 3

belongsToMany fires query with id 0

Hi, got the following migrations:

Schema::create('product_categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('slug')->unique()->index();
            $table->string('name')->unique();
            $table->string('teaser', 350);
            $table->integer('product_category_id')->unsigned()->nullable();
            $table->integer('image_id')->unsigned()->nullable();
            $table->timestamps();

            $table->foreign('product_category_id')->references('id')->on('product_categories')->onDelete('cascade');
            $table->foreign('image_id')->references('id')->on('images')->onDelete('set null');
        });

        Schema::create('product_to_category', function(Blueprint $table) {
            $table->increments('id');
            $table->integer('product_id')->unsigned();
            $table->integer('product_category_id')->unsigned();
            $table->timestamps();

            $table->foreign('product_category_id')->references('id')->on('product_categories')->onDelete('cascade');
            $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
        });

Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ProductCategory extends Model
{
    public function products()
    {
        return $this->belongsToMany(Product::class, 'product_to_category');
    }
}

The query is correct, but it set's the wrong id (0 instead of 1):

select `products`.*, `product_to_category`.`product_category_id` as `pivot_product_category_id`, `product_to_category`.`product_id` as `pivot_product_id` from `products` inner join `product_to_category` on `products`.`id` = `product_to_category`.`product_id` where `product_to_category`.`product_category_id` in (0)

Build a lot of Laravel applications, but I have no clue what's up here. Any idea?

0 likes
7 replies
Snapey's avatar

as you don't follow convention you probably need to fully specify foreign keys in each relation

36864's avatar

Could you dd() the category you're trying to use?

vnc00's avatar
Level 3

@36864 currently not at my work station, but I can tell you that the object looked correct. All attributes (also the id) were loaded correctly (Model attribute "primaryKey" also correct "id") and the relations were just empty Collections. If you need a specific info from the dd() category, I can paste it later.

36864's avatar

I tried reproducing your problem by importing your migrations and models but it just works fine on my end using tinker.

>>> App\ProductCategory::first()
=> App\ProductCategory {#786
     id: 1,
     slug: "k",
     name: "k",
     teaser: "k",
     product_category_id: null,
     image_id: null,
     created_at: "2017-07-28 09:56:08",
     updated_at: null,
   }
>>> App\ProductCategory::first()->products
=> Illuminate\Database\Eloquent\Collection {#790
     all: [
       App\Product {#789
         id: 1,
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#784
           product_category_id: 1,
           product_id: 1,
         },
       },
     ],
   }
>>> App\ProductCategory::with('products')->first()
=> App\ProductCategory {#796
     id: 1,
     slug: "k",
     name: "k",
     teaser: "k",
     product_category_id: null,
     image_id: null,
     created_at: "2017-07-28 09:56:08",
     updated_at: null,
     products: Illuminate\Database\Eloquent\Collection {#799
       all: [
         App\Product {#801
           id: 1,
           pivot: Illuminate\Database\Eloquent\Relations\Pivot {#800
             product_category_id: 1,
             product_id: 1,
           },
         },
       ],
     },
   }
>>>      

And for reference, thes were the generated sql queries

select `products`.*, `product_to_category`.`product_category_id` as `pivot_product_category_id`, `product_to_category`.`product_id` as `pivot_product_id` from `products` inner join `product_to_category` on `products`.`id` = `product_to_category`.`product_id` where `product_to_category`.`product_category_id` = '1';

select `products`.*, `product_to_category`.`product_category_id` as `pivot_product_category_id`, `product_to_category`.`product_id` as `pivot_product_id` from `products` inner join `product_to_category` on `products`.`id` = `product_to_category`.`product_id` where `product_to_category`.`product_category_id` in ('1');

I'm afraid we just don't have enough information to figure out what's going wrong in your application.

vnc00's avatar
Level 3

@36864 my query tries to use the "slug"? Why? I have absolutelty no idea, I never specified something with "slug". I also tried to remove the index() in the migration in product_category-table, same.

Take a look:

select `product_categories`.*, `product_to_category`.`product_id` as `pivot_product_id`, `product_to_category`.`product_category_id` as `pivot_product_category_id` from `product_categories` inner join `product_to_category` on `product_categories`.`slug` = `product_to_category`.`product_category_id` where `product_to_category`.`product_id` in (1)

When I change it to:

select `product_categories`.*, `product_to_category`.`product_id` as `pivot_product_id`, `product_to_category`.`product_category_id` as `pivot_product_category_id` from `product_categories` inner join `product_to_category` on `product_categories`.`id` = `product_to_category`.`product_category_id` where `product_to_category`.`product_id` in (1)

it works. So, why is Laravel using the "slug" instead of "id"?

vnc00's avatar
Level 3

GOD DAMN! Got it! I used "getKeyName" instead of "getRouteKeyName"... I'm so sorry! -.-

Please or to participate in this conversation.