[英]Laravel seed table with composite primary key
我需要使用復合主鍵創建一個表。 我一直在尋找解決問題的多個選項來創建一個AUTO_INCREMENT字段以及其他一些字段,並使它們成為復合主鍵,但最終我成功地這樣做了;
class CreateSpecificationTable extends Migration {
public function up()
{
Schema::create('specification', function(Blueprint $table){
$table->increments('specificationID');
$table->integer('categoryID', false, true);
$table->string('name', 100);
$table->dateTime('created_at');
$table->dateTime('updated_at')->nullable()->default(null);
$table->dateTime('deleted_at')->nullable()->default(null);
$table->foreign('categoryID')->references('categoryID')->on('categories');
});
DB::unprepared('ALTER TABLE specification DROP PRIMARY KEY, ADD PRIMARY KEY(specificationID, categoryID, name)');
}
該表的模型非常簡單:
class Specification extends Eloquent {
protected $table = 'specification';
protected $primaryKey = array('specificationID', 'categoryID', 'name');
}
然后播種機看起來像這樣:
class SpecificationSeeder extends Seeder {
public function run()
{
Specification::create(array(
'categoryID'=>1,
'name'=>'size',
));
Specification::create(array(
'categoryID'=>2,
'name'=>'resolution',
));
Specification::create(array(
'categoryID'=>1,
'naam'=>'connection',
));
}
}
但是,當我從CMD運行php artisan db:seed
命令時,我收到以下錯誤:
[ErrorException]
PDO::lastInsertId() expects parameter 1 to be string, array given
奇怪的是,我已經用這種方式在這個應用程序中構建了很多其他表,但這是第一個模型中protected $primaryKey
由帶有字段的數組組成,而不是只有一個主鍵。
此外,盡管給出了這個錯誤,第一個“種子”確實會添加到數據庫中,但之后沒有。
Eloquent不支持復合鍵。 您可以使用以下兩種方法之一來完成此工作:
1)使用Schema Builder作為Seeder並保持您的Migration不變。
class SpecificationSeeder extends Seeder {
public function run()
{
$data = array(
array(
'categoryID'=>1,
'name'=>'size',
),
array(
'categoryID'=>1,
'name'=>'size',
),
array(
'categoryID'=>1,
'naam'=>'connection',
)
);
DB::table('specification')->insert($data);
}
}
2)更改遷移,添加主鍵並定義唯一鍵。 離開播種機
class CreateSpecificationTable extends Migration {
public function up()
{
Schema::create('specification', function(Blueprint $table){
$table->increments('id');
$table->integer('specificationID');
$table->integer('categoryID', false, true);
$table->string('name', 100);
$table->dateTime('created_at');
$table->dateTime('updated_at')->nullable()->default(null);
$table->dateTime('deleted_at')->nullable()->default(null);
$table->unique( array('specificationID', 'categoryID', 'name') );
$table->foreign('categoryID')->references('categoryID')->on('categories');
});
}
}
Laravel 4確實支持復合鍵。 此外,最好還是正確設置主鍵,而不是使用foreign()語法。
如文檔中所述:
$table->primary('specificationID');
創建主鍵。 但是,因為你正在使用increments('id');
你已經有一個主鍵作為id。 因此,除非您實際存儲預定義且常量的規范的ID,否則您的列規范ID是冗余的。
$table->primary(array('specificationID', 'categoryID', 'name'));
創建一個復合鍵
一般來說,我會盡量保持你的綜合索引盡可能短,如果絕對必要,只包括列。 你真的需要為你的密鑰添加名字嗎? 我意識到對於較小的應用程序,這可能不那么重要,只是試圖說出最佳實踐。
我成功地讓Laravel 5.1使用復合鍵的方式。 首先將您的架構定義為:
class CreateSpecificationTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('specification', function(Blueprint $table){
$table->primary(array('specificationID', 'categoryID', 'name'));
$table->integer('categoryID', false, true);
$table->string('name', 100);
$table->dateTime('created_at');
$table->dateTime('updated_at')->nullable()->default(null);
$table->dateTime('deleted_at')->nullable()->default(null);
$table->foreign('categoryID')->references('categoryID')->on('categories');
});
}
你的型號:
class Specification extends Eloquent {
protected $table = 'specification';
protected $primaryKey = array('specificationID', 'categoryID', 'name');
public $incrementing = false; //important to avoid exception PDO::lastInsertId() expects parameter 1 to be string, array given
}
如果需要更新或刪除模型,則必須覆蓋 setKeysForSaveQuery
方法:
protected function setKeysForSaveQuery(\Illuminate\Database\Eloquent\Builder $query)
{
if(is_array($this->primaryKey)) {
foreach($this->primaryKey as $pk) {
$query->where($pk, '=', $this->original[$pk]);
}
return $query;
} else {
return parent::setKeysForSaveQuery($query);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.