FaqTrans
データベースを更新したいが、このデータベースには2つの主キー(faq_idaとlang)$table->primary(array('lang', 'faq_id'));
がある場合。したがって、auto_incrementを含むid
列は必要ありません。
ただし、次のコードを使用してデータベースを更新すると、エラーメッセージはid
列がないことを示しています。
$faq_trans = FaqTrans::where('faq_id','=',$faq_id)->where('lang','=',$lang)->first();
$faq_trans->lang = Input::get('lang');
$faq_trans->body = Input::get('body');
$faq_trans->title = Input::get('title');
$faq_trans->save();
エラーメッセージ
SQLSTATE [42S22]:列が見つかりません:1054不明な列 'id' in'where句 '(SQL:update
FAQtrans
setbody
=?、updated_at
=?ここで、id
はnullです)(バインディング:配列(0 => 'adfadaaadfadaa'、1 => '2013-07-04 11:12:42'、))
id
列を追加すると、コードは正常に機能します...
iD列なしでデータベースを更新する方法はありますか?
Laravel/Eloquentは複合主キーをサポートしていません。
Eloquent Modelクラスを確認すると、主キーは文字列のみであることがわかります。これは、WHERE句の作成に使用されます。
この行をモデルに書き込みます
public $primaryKey = '_id';
_idは手動の主キーです。
ものすごく単純:
FaqTrans::where(
[
'faq_id' => $faq_id,
'lang' => $lang
]
)->update(
[
'body' => $body,
'title' => $title
]
);
将来(私がしたように)この質問に出くわした人のために、Eloquentの複合主キーの素晴らしい回避策があります。
これは、モデルクラスの最上位になります。
_protected $primaryKey = array('key1', 'key2');
_
次に、モデルのsave()
メソッドを次のようにオーバーライドします。
_public function save(array $options = array())
{
if(!is_array($this->getKeyName()))
return parent::save($options);
// Fire Event for others to hook
if($this->fireModelEvent('saving') === false)
return false;
// Prepare query for inserting or updating
$query = $this->newQueryWithoutScopes();
// Perform Update
if ($this->exists) {
if (count($this->getDirty()) > 0) {
// Fire Event for others to hook
if ($this->fireModelEvent('updating') === false)
return false;
// Touch the timestamps
if ($this->timestamps)
$this->updateTimestamps();
//
// START FIX
//
// Convert primary key into an array if it's a single value
$primary = (count($this->getKeyName()) > 1) ? $this->getKeyName() : [$this->getKeyName()];
// Fetch the primary key(s) values before any changes
$unique = array_intersect_key($this->original, array_flip($primary));
// Fetch the primary key(s) values after any changes
$unique = !empty($unique) ? $unique : array_intersect_key($this->getAttributes(), array_flip($primary));
// Fetch the element of the array if the array contains only a single element
$unique = (count($unique) <> 1) ? $unique : reset($unique);
// Apply SQL logic
$query->where($unique);
//
// END FIX
//
// Update the records
$query->update($this->getDirty());
// Fire an event for hooking into
$this->fireModelEvent('updated', false);
}
// Perform Insert
} else {
// Fire an event for hooking into
if ($this->fireModelEvent('creating') === false)
return false;
// Touch the timestamps
if ($this->timestamps)
$this->updateTimestamps();
// Retrieve the attributes
$attributes = $this->attributes;
if ($this->incrementing && !is_array($this->getKeyName()))
$this->insertAndSetId($query, $attributes);
else
$query->insert($attributes);
// Set exists to true in case someone tries to update it during an event
$this->exists = true;
// Fire an event for hooking into
$this->fireModelEvent('created', false);
}
// Fires an event
$this->fireModelEvent('saved', false);
// Sync
$this->original = $this->attributes;
// Touches all relations
if (array_get($options, 'touch', true))
$this->touchOwners();
return true;
}
_
元のソース: https://github.com/laravel/framework/issues/5517#issuecomment-5299661
2016-05-03を更新
これを行うための私の新しいお気に入りの方法:
Laravel 5? のモデルに複合キーを配置するにはどうすればよいですか?
FaqTrans
モデルに移動し、これを追加します。
public $key = 'faq_id';
faq_id
がlang
よりも重要であると仮定すると、これで十分です。