我有这样的多对多关系:
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模型的愉快体验。
答案 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获得对复合主键的支持。