Laravelでは、次のように関係を設定できます。
class User {
public function items()
{
return $this->belongsToMany('Item');
}
}
ユーザーがピボットテーブル内のすべてのアイテムを取得できるようにします。
Auth::user()->items();
しかし、それとは逆のことをしたい場合はどうでしょうそして、ユーザーがまだ持っていないすべてのアイテムを取得します。したがって、ピボットテーブルにはありません。
これを行う簡単な方法はありますか?
単純さと対称性のために、Userモデルに新しいメソッドを作成できます。
// User model
public function availableItems()
{
$ids = \DB::table('item_user')->where('user_id', '=', $this->id)->lists('user_id');
return \Item::whereNotIn('id', $ids)->get();
}
通話を使用するには:
Auth::user()->availableItems();
クラスのソースコードを見るIlluminate\Database\Eloquent\Builder
、これを行うLaravelには2つのメソッドがあります:whereDoesntHave
(whereHas
の反対)とdoesntHave
(has
)
// SELECT * FROM users WHERE ((SELECT count(*) FROM roles WHERE user.role_id = roles.id AND id = 1) < 1) AND ...
User::whereDoesntHave('Role', function ($query) use($id) {
$query->whereId($id);
})
->get();
これは私にとって正しく機能します!
単純な「存在しない関係」の場合、これを使用します。
User::doesntHave('Role')->get();
英語が理解できません。私はグーグル翻訳機を使いました。
それほど単純ではありませんが、通常、最も効率的な方法はサブクエリを使用することです。
$items = Item::whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
})
->get();
これが私がよくやったことなら、スコープメソッドとしてItemモデルに追加します。
class Item extends Eloquent {
public function scopeWhereNotRelatedToUser($query, $user_id)
{
$query->whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
});
}
}
その後、このように使用します。
$items = Item::whereNotRelatedToUser($user_id)->get();
左結合はどうですか?
テーブルがusers
、items
、item_user
であるとすると、ユーザーに関連付けられていないすべてのitems
を検索します123
:
DB::table('items')->leftJoin(
'item_user', function ($join) {
$join->on('items.id', '=', 'item_user.item_id')
->where('item_user.user_id', '=', 123);
})
->whereNull('item_user.item_id')
->get();
そのため、次のようなスコープを作成することになりました。
public function scopeAvail($query)
{
return $query->join('item_user', 'items.id', '<>', 'item_user.item_id')->where('item_user.user_id', Auth::user()->id);
}
その後、次を呼び出します。
Items::avail()->get();
現時点では機能しますが、少し面倒です。 not
のようなキーワードで何かを見たいですか:
Auth::user()->itemsNot();
基本的にEloquentは上記のクエリを実行していますが、=
の代わりに<>
。
多分あなたは使うことができます:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
これはあなたのために働くはずです
$someuser = Auth::user();
$someusers_items = $someuser->related()->lists('item_id');
$all_items = Item::all()->lists('id');
$someuser_doesnt_have_items = array_diff($all_items, $someusers_items);