2

我有这样的多对多关系:

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 表中的列,而不是 user_blocks 表。这只是一个 sql 错误,其中用户表正在尝试使用不存在的列进行更新unblocked

我已经尝试在示例中为 $blocked_user 添加->pivot->pivot()分配。第一个在 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 进行优化,但这是将 eloquent 移植到具有预先建立模式的 Codeigniter 项目中。使用 Codeigniter 模型的其他愉快体验。

4

1 回答 1

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 获得对复合主键的支持之前它确实有效。

于 2013-03-11T15:37:03.813 回答