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_blocks テーブルではなく、user テーブルの列を更新したいと考えているようです。これは単純に、ユーザー テーブルが存在しない列で更新されようとしている場合の SQL エラーunblockedです。

例の $blocked_user の割り当てに->pivotandを追加してみました。->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');
}

複合主キーを使用して Eloquent モデルを定義する方法がわからないため、user_blocks テーブルのモデルはありません (どこでも検索しましたが、誰も尋ねた質問ではないようです)。

スキーマがEloquent用に最適化されていないことは認識していますが、これは事前に確立されたスキーマを持つCodeigniterプロジェクトに雄弁を移植しています. Codeigniter モデルを使用するよりも、そうでなければ楽しい経験です。

4

1 に答える 1

4

Eloquent は現在、複合主キーを明示的に処理していないようです。しかし、user_blocks テーブルのモデルを作成し、主キーを 1 つだけ指定することで問題を解決できました。

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 に答える