Ответ 1
Laravel/Eloquent не поддерживает составные первичные ключи.
Когда вы проверяете класс Eloquent Model, вы можете видеть, что первичный ключ может быть только строкой, которая используется для создания предложения WHERE.
Когда я хочу обновить базу данных FaqTrans
, но у этой базы данных есть два первичных ключа (faq_ida и lang) $table->primary(array('lang', 'faq_id'));
. поэтому мне не нужен столбец id
с auto_increment.
Однако, когда я использую следующий код для обновления базы данных, сообщение об ошибке подсказывает мне, что нет столбца 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 'где clause '(SQL: update
FaqTrans
setbody
=?,updated_at
=? гдеid
равно null) (Привязки: array (0 = > 'adfadaaadfadaa', 1 = > '2013-07-04 11:12:42',))
и когда я добавил столбец id
, код отлично работает...
Есть ли способ обновить базу данных без столбца ID?
Laravel/Eloquent не поддерживает составные первичные ключи.
Когда вы проверяете класс Eloquent Model, вы можете видеть, что первичный ключ может быть только строкой, которая используется для создания предложения WHERE.
Запишите эту строку в свою модель
public $primaryKey = '_id';
Где _id - ваш основной первичный ключ
Для тех, кто наткнется на этот вопрос в будущем (как и я), вот хороший обходной путь для составного первичного ключа в 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 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-52996610
Обновление 2016-05-03
Мой новый любимый способ сделать это:
Как я могу поместить составные клавиши в модели в Laravel 5?
Довольно просто:
FaqTrans::where(
[
'faq_id' => $faq_id,
'lang' => $lang
]
)->update(
[
'body' => $body,
'title' => $title
]
);
Перейдите в свою модель FaqTrans
и добавьте это.
public $key = 'faq_id';
Это должно сделать это, считая faq_id
более важным, чем lang
Если у кого-то такая же проблема.
Я использовал ответ Нишита Дханани, и он работал очень хорошо, что было:
Напишите эту строку в своей модели
public $primaryKey = '_id';
Где _id - ваш ручной первичный ключ
В моем случае. У меня была пользовательская таблица, и часть моих пользователей - это студенты. Таким образом, основным ключом в таблице моих учеников был "user_id".
Добавление этой строки в мою модель для учащихся: public $primaryKey = 'user_id';
Я смог использовать метод save() при обновлении объекта студента.
Надеюсь, что это поможет