Eloquent 知道实际的主(复合)键时遇到问题
Trouble with Eloquent knowing actual primary (composite) key
数据库中有一个 table 具有以下初始迁移:
public function up()
{
Schema::create('products_markets', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products');
$table->integer('country_code_id')->unsigned();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
$sql = 'ALTER TABLE `products_markets` ADD UNIQUE `unique_index`(`product_id`, `country_code_id`)';
DB::connection()->getPdo()->exec($sql);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products_markets');
}
一切正常;但是,一旦 拥有自动递增的主键就没有意义 id
进行了新的迁移:
public function up()
{
Schema::table('products_markets', function (Blueprint $table) {
DB::unprepared("ALTER TABLE products_markets ADD INDEX country_code_id (country_code_id)");
DB::unprepared('ALTER TABLE products_markets MODIFY id INT NOT NULL');
DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
DB::unprepared('ALTER TABLE products_markets DROP COLUMN id');
DB::unprepared('ALTER TABLE products_markets ADD PRIMARY KEY (country_code_id, product_id)');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('products_markets', function (Blueprint $table) {
DB::unprepared('DROP INDEX country_code_id ON products_markets');
DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
$table->increments('id');
});
}
虽然此代码在我们的服务器和本地一些机器上工作,但其他机器似乎在测试期间抛出错误:
ProductTest::test_scopeMarket_only_returns_products_for_user_country
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found:
1054 Unknown column 'id' in 'where clause' (SQL: update
products_markets
set country_code_id
= 121, updated_at
=
2016-08-29 17:05:21 where id
is null)
以下行中的问题测试错误:
$products[0]->markets()->first()->update(['country_code_id' => 121]);
我们有composer dumpautoload,重新迁移,清除缓存;然而,似乎没有任何帮助。这与使用 DB::unprepared
到 ALTER
和 table 有关系吗?
答案是eloquent does not support composite primary keys.
如果你 运行 :
$products[0]->markets()->update(['country_code_id' => 121]);
会运行;但是,如果您 运行:
$products[0]->markets()->get()->update(['country_code_id' => 121]);
它会失败,因为 first() returns 模型和默认模型主键是 id
并且复合 primaryKey
s 不由 Eloquent 处理。
数据库中有一个 table 具有以下初始迁移:
public function up()
{
Schema::create('products_markets', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products');
$table->integer('country_code_id')->unsigned();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();
});
$sql = 'ALTER TABLE `products_markets` ADD UNIQUE `unique_index`(`product_id`, `country_code_id`)';
DB::connection()->getPdo()->exec($sql);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products_markets');
}
一切正常;但是,一旦 id
进行了新的迁移:
public function up()
{
Schema::table('products_markets', function (Blueprint $table) {
DB::unprepared("ALTER TABLE products_markets ADD INDEX country_code_id (country_code_id)");
DB::unprepared('ALTER TABLE products_markets MODIFY id INT NOT NULL');
DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
DB::unprepared('ALTER TABLE products_markets DROP COLUMN id');
DB::unprepared('ALTER TABLE products_markets ADD PRIMARY KEY (country_code_id, product_id)');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('products_markets', function (Blueprint $table) {
DB::unprepared('DROP INDEX country_code_id ON products_markets');
DB::unprepared('ALTER TABLE products_markets DROP PRIMARY KEY');
$table->increments('id');
});
}
虽然此代码在我们的服务器和本地一些机器上工作,但其他机器似乎在测试期间抛出错误:
ProductTest::test_scopeMarket_only_returns_products_for_user_country Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: update
products_markets
setcountry_code_id
= 121,updated_at
= 2016-08-29 17:05:21 whereid
is null)
以下行中的问题测试错误:
$products[0]->markets()->first()->update(['country_code_id' => 121]);
我们有composer dumpautoload,重新迁移,清除缓存;然而,似乎没有任何帮助。这与使用 DB::unprepared
到 ALTER
和 table 有关系吗?
答案是eloquent does not support composite primary keys.
如果你 运行 :
$products[0]->markets()->update(['country_code_id' => 121]);
会运行;但是,如果您 运行:
$products[0]->markets()->get()->update(['country_code_id' => 121]);
它会失败,因为 first() returns 模型和默认模型主键是 id
并且复合 primaryKey
s 不由 Eloquent 处理。