不在数据透视表中的地方

Rob*_*Rob 27 pivot-table laravel eloquent laravel-4

在Laravel中我们可以设置如下关系:

class User {
    public function items()
    {
        return $this->belongsToMany('Item');
    }
}
Run Code Online (Sandbox Code Playgroud)

允许我们为用户获取数据透视表中的所有项:

Auth::user()->items();
Run Code Online (Sandbox Code Playgroud)

但是,如果我想得到相反的结果呢?并获得用户尚未拥有的所有项目.所以不要在数据透视表中.

有一个简单的方法吗?

Wal*_*ers 45

看一下这个类的源代码Illuminate\Database\Eloquent\Builder,我们在Laravel中有两个方法可以做到这一点:( 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();
Run Code Online (Sandbox Code Playgroud)

这对我来说正常!

对于简单的"Where not exists relationship",请使用:

User::doesntHave('Role')->get();
Run Code Online (Sandbox Code Playgroud)

对不起,不懂英文.我使用谷歌翻译.

  • 这绝对应该是正确的答案 (6认同)

Mak*_*ita 13

为简单和对称,您可以在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();
}
Run Code Online (Sandbox Code Playgroud)

使用电话:

Auth::user()->availableItems();
Run Code Online (Sandbox Code Playgroud)

  • 在 Laravel 5.5+ 中,你可以用 `-&gt;pluck('user_id)` 交换 `-&gt;lists('user_id')` 方法 (2认同)

Col*_*mes 6

它不是那么简单,但通常最有效的方法是使用子查询.

$items = Item::whereNotIn('id', function ($query) use ($user_id)
    {
        $query->select('item_id')
            ->table('item_user')
            ->where('user_id', '=', $user_id);
    })
    ->get();
Run Code Online (Sandbox Code Playgroud)

如果这是我经常做的事情,我会将它作为范围方法添加到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);
        });
    }

}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它.

$items = Item::whereNotRelatedToUser($user_id)->get();
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用**laravel 5**并且不得不用` - >替换` - > table`.否则我得到一个*BadMethodCallException调用未定义的方法Illuminate\Database\Query\Builder :: table()* (4认同)