Laravel 4 Eloquent ORM:如何更新具有复合主键的数据透视表条目

时间:2013-03-08 20:21:23

标签: laravel many-to-many laravel-4 eloquent composite-key

我有这样的多对多关系:

user
 - user_id

user_blocks
 - blocker_user_id
 - blocked_user_id
 - unblocked (Timestamp)

其中blocker和blocked_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进行更新。

我尝试在示例中为$ blocked_user的分配添加->pivot->pivot()。第一个在Eloquent \ Model :: performUpdate,Call to a member function update() on a non-object中给出了一个错误,后者在Eloquent \ Builder :: __调用中给了我call_user_func_array() expects parameter 1 to be a valid callback, class 'Illuminate\Database\Query\Builder' does not have a method 'pivot'

用户表的模型将自身的关系定义为:

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

user_blocks表没有模型,因为我不知道如何使用复合主键定义Eloquent模型(我已经到处搜索过,这似乎不是任何人提出的问题)。

我意识到该模式不是针对Eloquent进行优化的,但是这是一个雄辩的嫁接到具有预先建立的模式的Codeigniter项目。使用Codeigniter模型的愉快体验。

1 个答案:

答案 0 :(得分:4)

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获得对复合主键的支持。