简体   繁体   中英

Laravel relationship - not unique table alias

I am getting the following error

SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'contacts' (SQL: select * from (select `item_meta`.*, max(case when `item_meta`.`id` = test then 150 else 0 end + case when `item_meta`.`id` like test% then 50 else 0 end + case when `item_meta`.`id` like %test% then 10 else 0 end + case when `item_meta`.`name` = test then 120 else 0 end + case when `item_meta`.`name` like test% then 40 else 0 end + case when `item_meta`.`name` like %test% then 8 else 0 end + case when `contacts`.`name` = test then 45 else 0 end + case when `contacts`.`name` like test% then 15 else 0 end + case when `contacts`.`name` like %test% then 3 else 0 end + case when `contacts`.`name` = test then 45 else 0 end + case when `contacts`.`name` like test% then 15 else 0 end + case when `contacts`.`name` like %test% then 3 else 0 end) as relevance from `item_meta` left join `contact_manufacturer_to_meta` on `contact_manufacturer_to_meta`.`meta_id` = `item_meta`.`id` left join `contacts` on `contact_manufacturer_to_meta`.`contact_id` = `contacts`.`id` left join `contact_vendor_to_meta` on `contact_vendor_to_meta`.`meta_id` = `item_meta`.`id` left join `contacts` on `contact_vendor_to_meta`.`contact_id` = `contacts`.`id` where (`item_meta`.`id` like %test% or `item_meta`.`name` like %test% or `contacts`.`name` like %test% or `contacts`.`name` like %test%) and `item_meta`.`company_id` = 1 group by `item_meta`.`id`) as `item_meta` where `relevance` >= 6.00 and `item_meta`.`deleted_at` is null order by `relevance` desc limit 10)

Which is caused by me having the same table for two pivot tables, the database structure is below.

Schema::create('contacts', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

Schema::create('contact_manufacturer_to_item', function (Blueprint $table) {
        $table->integer('item_id')->unsigned();
        $table->integer('contact_id')->unsigned();
        $table->string('manufacturer_part_number')->nullable();
        $table->timestamps();

        $table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');
        $table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');

        $table->primary(['item_id', 'contact_id']);
    });

Schema::create('contact_vendor_to_item', function (Blueprint $table) {
        $table->integer('item_id')->unsigned();
        $table->integer('contact_id')->unsigned();
        $table->string('vendor_part_number')->nullable();
        $table->timestamps();

        $table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');
        $table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');

        $table->primary(['item_id', 'contact_id']);
    });

Controller code causing the issue is based off the Eloquence package for the search

return Item::with('vendors')->with('manufacturers')->search($query, [
                'id' => 10,
                'name' => 8,
                'manufacturers.name' => 3,
                'vendors.name' => 3,
            ])
            ->limit($limit)
            ->get();

Model code

protected $table = 'item_meta';

public function vendors() {
    return $this->belongsToMany('App\Contact', 'contact_vendor_to_meta', 'meta_id', 'contact_id');
}

public function manufacturers() {
    return $this->belongsToMany('App\Contact', 'contact_manufacturer_to_meta', 'meta_id', 'contact_id');
}

Is there anything I can do to solve this issue, without having to do a RAW SQL query for the searching?

This is the literal translation of you eloquent query:

return Item::with('vendors' => function ($query) {
  $query->where('name', 3);
}])
  ->with('manufacturers' => function ($query) {
    $query->where('name', 3);
})
  ->where([['id' => 10], ['name', 8]])
  ->limit($limit)
  ->get();

But that won't work neither. What you probable want to achieve is this:

return Item::with('vendors' => function ($query) {
  $query->where('id', 3); //$vendor_id or $vendor_name?
}])
  ->with('manufacturers' => function ($query) {
    $query->where('id', 3); //$manufacturer_id or $manufacturer_name?
})
  ->where('id', 10) //$item_id or $item_name?
  ->where('name', 8)
  ->limit($limit)
  ->get();

It is still not clear what you want to search. If you want the id (or name) or an item, you don't need to search in vendor or manufacturer. Your name is confusing, for it's an integer, not a string. There is no name in your migration schema. Are these names in manufacturers and venders ? It's confusing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM