2

如何用 Eloquent 查询所有没有某种类型证书的用户?

拉拉维尔 4

我有两张桌子:

users table:
   ->id
   ->name


certificats table:
    ->id
    ->user_id
    ->certificate_type

我已经为此苦苦挣扎了好几个小时。我尝试的最后一件事是:

$users = User::with(array('certificate' => function($query)
{
    $query->where('type','!=','SL');
}))->get();

这给了我所有的用户,但我试图让所有没有证书类型“SL”的用户。

-- 编辑: Spencer7593 下面的原始查询有效。但我没有让雄辩的查询起作用。

SELECT u.*
FROM users u
LEFT
JOIN certificates c
ON c.user_id = u.id
AND c.type = 'SL'
WHERE c.user_id IS NULL

关系:

public function certificate(){
    return $this->hasMany('Certificate');
}

public function certificate(){
    return $this->belongsTo('User');
}
4

2 回答 2

1

获取所需结果集的 SQL 相当简单。

SELECT u.*
  FROM users u
  LEFT
  JOIN certificates c
    ON c.user_id = u.id
   AND c.type = 'SL'
 WHERE c.user_id IS NULL

这是一种熟悉的模式,称为“反连接”。基本上,这是一个 LEFT JOIN 查找匹配的行,以及users不匹配的行,然后过滤掉所有匹配的行,剩下的users就是不匹配的行。

诀窍是让 Eloquent 为您生成该 SQL。为了让 Eloquent 做到这一点,你需要告诉 eloquent 做一个 LEFT JOIN,并添加一个 WHERE 子句,

也许这样的事情会很接近:

->left_join('certificate AS c', function($join){
      $join->on('c.user_id','=','user.id');
      $join->and_on('c.type','=','SL');
  })
->where_null('c.user_id')

跟进

(为了那些可能没有阅读评论的人的利益)

Klass Terst (OP),在 Eloquent 的尝试中报告了语法问题(在上面的答案中):left_join需要替换为leftJoin,并且and_on无法识别。(后者可能是我的发明,基于 with where, and_where,中使用的约定or_where。)

$users = DB::table('users')
  ->select('users.id','users.name')
  ->leftJoin('certificate AS c', function($join){
     $join->on('c.user_id','=','user.id');
     $join->on('c.type','=','SL'); 
  })
  ->where_null('c.user_id');
于 2013-07-22T15:14:46.387 回答
0

我相信问题出在你的人际关系上。

楷模

class User extends Eloquent
{
    public function certificates()
    {
        return $this->hasMany('Certificate');
    }
}

class Certificate extends Eloquent
{
    public function user()
    {
        return $this->belongsTo('User');
    }
}

控制器

$users = User::with(array('certificates' => function($query)
{
    $query->where('type','!=','SL');
}))->get();
return View::make('yourView')->with('users',$users);

看法

@foreach($users as $user)
    {{ $user->name }} // User's name
    @foreach($user->certificates as $certificate)
        {{ $certificate->certificate_type }} // Certificate type shouldn't be 'SL'
    @endforeach
@endforeach

我希望这有帮助!

于 2013-07-22T18:32:30.997 回答