Laravel 4.2-带有OR和reverse参数的Eloquent WHERE子句


Laravel 4.2 - Eloquent WHERE clause with OR and reverse parameters

我在Laravel 4.2中有Eloquent语句,看起来像这个

    $user_message_block = Message::where('responder_id', '=', Auth::user()->id)
                        ->where('user_id', '=', $user->id)->first();

然后,如果$user_message_block不存在,我还必须检查一个相反的情况,我这样做。。。

    if(!$user_message_block){
        $user_message_block = Message::where('responder_id', '=', Auth::user()->id)
                            ->where('user_id', '=', $user->id)->first();
    }

我真正想做的是运行一个查询,同时检查两种情况。。

在伪表达式中,我需要这样的东西:

$user_message_block = Message::where('responder_id', '=', Auth::user()->id, 
                                 'AND', 'user_id', '=', $user->id, 
                                 'OR', 'responder_id', '=', $user->id, 
                                 'AND', 'user_id', '=', Auth::user()->id)->first();

所以基本上我需要

SELECT Message where (responder_id=x AND user_id=y) OR where (responder_id=y AND user_id=x)

我怎么能用Eloquent做到这一点。我找不到更多关于Eloquent使用的OR和and语句的信息。

谢谢!

更新:

经过更多的研究,我发现这似乎工作(仍在测试很多)

$user_message_block = 
        Message::where(['responder_id' => Auth::user()->id, 'user_id' => $user->id])
             ->orWhere(['user_id' => Auth::user()->id, 'responder_id' => $user->id])
             ->first();

$user_message_block = 
        Message::where(['responder_id' => Auth::user()->id, 'user_id' => $user->id])
             ->orWhere(['user_id' => Auth::user()->id, 'responder_id' => $user->id])
             ->get();

这有什么缺点需要我考虑吗?

在Eloquent中执行这项操作可能非常复杂,但这正是您使用Laravel的查询生成器所需要的,而无需恢复到原始SQL。

    DB::table('messages')
        ->where(function($query)
        {
            $query->where('responder_id', '=', 'x')
            ->where('user_id', '=', 'y');
        })
        ->orWhere(function($query) {
            $query->where('responder_id', '=', 'y')
                  ->where('user_id', '=', 'x');
        })
        ->get();

这是我在上面运行toSql()得到的:

select * from `messages` where (`responder_id` = ? and `user_id` = ?) or (`responder_id` = ? and `user_id` = ?)

试试这个,看看它是否适用于Eloquent。

Message::where(function($query) {
    $query->where('responder_id', '=', 'x')
          ->where('user_id', '=', 'y');
})->orWhere(function($query) {
    $query->where('responder_id', '=', 'y')
          ->where('user_id', '=', 'x');
})->get();

它应该起作用。

我将解决方案归功于Noah,因为他提供了一个有效的解决方案,并为帮助我做出了努力。然而,我最终使用了不同的解决方案。。

$user_message_block = 
    Message::where(['responder_id' => 'x', 'user_id'      => 'y'])
           ->orWhere(['user_id'    => 'x', 'responder_id' => 'y'])
           ->get();

在我的特殊情况下,我只需要找到第一条记录,所以这对我来说是有效的

$user_message_block = 
    Message::where(['responder_id' => 'x', 'user_id'      => 'y'])
           ->orWhere(['user_id'    => 'x', 'responder_id' => 'y'])
           ->first();

可以说,我在亚历克斯的phpacademy视频中找到了一个类似于我的解决方案。我偶然发现了这个Laravel雄辩的SQL查询,它带有OR和And子句