Posted at

Laravel4, Eloquentはcomposite keyに対応していない

More than 5 years have passed since last update.

Laravel4でEloquentを使用していたらデータの挿入でハマったのでメモっておく

http://laravel4.kore1server.com/docs/queries

http://laravel4.kore1server.com/docs/eloquent

http://stackoverflow.com/questions/17461383/how-can-i-update-data-with-eloquent-without-id-in-laravel-4


composite keyのテーブル作成

:~/laravel_test$ php artisan migrate:make create_hogefuga_table

Created Migration: 2014_09_24_212126_create_hogefuga_table
Generating optimized class loader
Compiling common classes
Compiling views


create_hogefuga_table.php

    ・・・

public function up()
{
//
Schema::create('hogefuga',function($table)
{
$table->integer('hoge');
$table->integer('fuga');
$table->integer('bar');
$table->timestamps();
$table->primary(array('hoge','fuga'));
});
}

public function down()
{
//
Schema::drop('hogefuga');
}


| hogefuga | CREATE TABLE `hogefuga` (

`hoge` int(11) NOT NULL,
`fuga` int(11) NOT NULL,
`bar` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`hoge`,`fuga`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |


モデルの作成

Eloquentでは主キーがidでない場合は上書きして設定するので以下のようにarrayを入れておく


Hogefuga.php

class Hogefuga extends Eloquent{

protected $table = 'hogefuga';
protected $primaryKey = array('hoge','fuga');

public function get_by_pkey($hoge,$fuga)
{
$hogefuga_rec = $this->where('hoge','=',$hoge)->where('fuga','=',$fuga)->get();
return $hogefuga_rec;
}

public function insert_data($hoge,$fuga,$bar)
{
$this->hoge = $hoge;
$this->fuga = $fuga;
$this->bar = $bar;
$this->save();
}

}



Routeの作成

Route::get('hogefuga_insert/{hoge}/{fuga}/{bar}','Hogefugabar@insert_call');

Route::get('hogefuga_look/{hoge}/{fuga}','Hogefugabar@rec_dump');


Controllerの作成


Hogefugabar.php

class Hogefugabar extends BaseController{

public function insert_call($hoge,$fuga,$bar)
{
$HogefugaModel = new Hogefuga;
$HogefugaModel->insert_data($hoge,$fuga,$bar);

return 'inserted!';
}

public function rec_dump($hoge,$fuga)
{
$HogefugaModel = new Hogefuga;
$recs = $HogefugaModel->get_by_pkey($hoge,$fuga);

return $recs[0]->hoge;
}

}



レコードを入れてみる

laravel.dev:8080/hogefuga_insert/10/3/3

とかURL指定してテーブルにレコードを挿入しようとすると

something went wrongと怒られる。

しかしDBを直接見てみるとレコードは挿入されている

laravel.dev:8080/hogefuga_look/10/3にアクセスするとデータの取得は出来る

app/storage/logs/laravel.logを見てみると

... production.ERROR: exception 'ErrorException' with message 'PDO::lastInsertId() expects parameter ...

みたいなことを言われている。

Eloquentがcomposite keyに対応していないので起こるようだ。

テーブルの主キーが単一でないと今のところは$this->save()とかやってはいけないようだ。

というわけでクエリービルダーを使用してレコードを挿入するようにする


Hogefuga.php

      public function insert_data($hoge,$fuga,$bar)

{
$data = array('hoge'=>$hoge,'fuga'=>$fuga,'bar'=>$bar);
DB::table($this->table)->insert($data);
}

パラメータを変えてアクセスすると、今度はエラーが無くデータを入れることができた