Laravel 4 Eloquent ORM: как обновить запись сводной таблицы с составными первичными ключами

У меня есть отношение «многие ко многим», например:

user
 - user_id

user_blocks
 - blocker_user_id
 - blocked_user_id
 - unblocked (Timestamp)

Где blocker и block_user_id являются составным первичным ключом, оба существуют как внешние ключи для user_id пользовательской таблицы. Обе таблицы являются InnoDB.

Когда я пытаюсь сделать следующее:

$user = User::find(1)
$blocked_user = $user->blocked()->where('blocked_user_id', 2)->first();

$blocked_user->unblocked = User::freshTimestamp();
$blocked_user->save();

Кажется, я хочу обновить столбец в пользовательской таблице, а не в таблице user_blocks. Это просто ошибка sql, когда пользовательская таблица пытается обновить несуществующий столбец unblocked.

Я попытался добавить ->pivot и ->pivot() к назначению для $blocked_user в примере. Первый выдает ошибку в Eloquent\Model::performUpdate, Call to a member function update() on a non-object, а второй выдает call_user_func_array() expects parameter 1 to be a valid callback, class 'Illuminate\Database\Query\Builder' does not have a method 'pivot' в Eloquent\Builder::__call.

Модель пользовательской таблицы определяет отношение к самой себе как:

public function blocked() {
    return $this->belongsToMany(
        'User', 
        'user_blocks', 
        'blocker_user_id', 
        'blocked_user_id'
    )->withPivot('unblocked');
}

Для таблицы user_blocks нет модели, так как я не знаю, как определить модель Eloquent с составным первичным ключом (я искал везде, и, похоже, никто не задавал этот вопрос).

Я понимаю, что схема недостаточно оптимизирована для Eloquent, но это привнесение красноречия в проект Codeigniter с предварительно установленной схемой. В остальном приятный опыт использования моделей Codeigniter.


person epocsquadron    schedule 08.03.2013    source источник
comment
Я создал запрос на вытягивание, который пытается реализовать эту важную, но недостающую функцию: github.com/laravel /framework/pull/1891   -  person igorsantos07    schedule 17.07.2013


Ответы (1)


Похоже, что в настоящее время Eloquent явно не обрабатывает составные первичные ключи. Однако мне удалось решить проблему, сделав модель таблицы user_blocks и указав только один из первичных ключей:

class Blocker extends Model {

    protected $table = "user_blocks";
    protected $primaryKey = "blocker_user_id";
    public $timestamps = false; // Don't track nonexistent created_at/updated_at columns

}

Затем в логике обновления разблокированного столбца я просто сделал следующее:

$blocked_user = Blocker::where('blocker_user_id', $user->user_id)
    ->where('blocked_user_id', $user_to_be_unblocked_id)
    ->first();

$blocked_user->unblocked = Blocker::freshTimestamp();

$blocked_user->save();

Это не самый элегантный способ решения проблемы, но он работает до тех пор, пока Eloquent не получит поддержку составных первичных ключей.

person epocsquadron    schedule 11.03.2013