簡體   English   中英

Laravel種子表與復合主鍵

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM