Как обновить данные с помощью Eloquent без id в Laravel 4

Когда я хочу обновить базу данных 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 set body =?, updated_at =? где id равно null) (Привязки: array (0 = > 'adfadaaadfadaa', 1 = > '2013-07-04 11:12:42',))

и когда я добавил столбец id, код отлично работает...

Есть ли способ обновить базу данных без столбца ID?

Ответы

Ответ 1

Laravel/Eloquent не поддерживает составные первичные ключи.

Когда вы проверяете класс Eloquent Model, вы можете видеть, что первичный ключ может быть только строкой, которая используется для создания предложения WHERE.

Ответ 2

Запишите эту строку в свою модель

public $primaryKey = '_id';

Где _id - ваш основной первичный ключ

Ответ 3

Для тех, кто наткнется на этот вопрос в будущем (как и я), вот хороший обходной путь для составного первичного ключа в 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?

Ответ 4

Довольно просто:

FaqTrans::where(
            [
                'faq_id' => $faq_id,
                'lang' => $lang
            ]
        )->update(
            [
                'body' => $body,
                'title' => $title
            ]
        );

Ответ 5

Перейдите в свою модель FaqTrans и добавьте это.

public $key = 'faq_id';

Это должно сделать это, считая faq_id более важным, чем lang

Ответ 6

Если у кого-то такая же проблема. Я использовал ответ Нишита Дханани, и он работал очень хорошо, что было: Напишите эту строку в своей модели
 public $primaryKey = '_id';
Где _id - ваш ручной первичный ключ

В моем случае. У меня была пользовательская таблица, и часть моих пользователей - это студенты. Таким образом, основным ключом в таблице моих учеников был "user_id".
Добавление этой строки в мою модель для учащихся: public $primaryKey = 'user_id';

Я смог использовать метод save() при обновлении объекта студента.

Надеюсь, что это поможет