Php 关系对象上的Laravel where

Php 关系对象上的Laravel where,php,laravel,eloquent,relationship,where-clause,Php,Laravel,Eloquent,Relationship,Where Clause,我正在用Laravel5.0开发一个web API,但我不确定我正在尝试构建的具体查询 我的课程如下: class Event extends Model { protected $table = 'events'; public $timestamps = false; public function participants() { return $this->hasMany('App\Participant', 'IDEvent',

我正在用Laravel5.0开发一个web API,但我不确定我正在尝试构建的具体查询

我的课程如下:

class Event extends Model {

    protected $table = 'events';
    public $timestamps = false;

    public function participants()
    {
        return $this->hasMany('App\Participant', 'IDEvent', 'ID');
    }

    public function owner()
    {
        return $this->hasOne('App\User', 'ID', 'IDOwner');
    }
}

现在,我想了解所有特定参与者的活动。 我试过:

Event::with('participants')->where('IDUser', 1)->get();
但是
where
条件应用于
事件
,而不是其
参与者
。以下是一个例外:

Participant::where('IDUser', 1)->event()->get();
我知道我可以这样写:

$list = Participant::where('IDUser', 1)->get();
for($item in $list) {
   $event = $item->event;
   // ... other code ...
}
但是向服务器发送这么多查询似乎不是很有效


使用Laravel 5和Eloquent通过模型关系执行
where
的最佳方法是什么?

对关系执行此操作的正确语法是:

Event::whereHas('participants', function ($query) {
    return $query->where('IDUser', '=', 1);
})->get();
这将返回参与者的用户ID为1的事件。如果参与者的用户ID不是1,则不会返回事件


更多信息请访问

@Cermbo的答案与此问题无关。在这个答案中,
Laravel
将为您提供所有
事件
,前提是每个
事件
都有
参与者
,其中
IdUser
1

但是,如果您希望获得所有
参与者的所有
事件
,前提是所有
参与者的
id user
为1,那么您应该执行以下操作:

Event::with(["participants" => function($q){
    $q->where('participants.IdUser', '=', 1);
}])
注:

中,其中
使用表名,而不是模型名

    return Deal::with(["redeem" => function($q){
        $q->where('user_id', '=', 1);
    }])->get();

这对我来说很有效

对于多个连接,请使用类似以下代码的代码:

$someId = 44;
Event::with(["owner", "participants" => function($q) use($someId){
    $q->where('participants.IdUser', '=', 1);
    //$q->where('some other field', $someId);
}])

我在BaseModel中创建了一个自定义查询范围(我的所有模型都扩展了这个类):

您可以在许多上下文中使用它,例如:

Event::whereHasRelated('participants', 1)->isNotEmpty(); // where has participant with id = 1 
此外,您可以尝试省略关系名称并仅传递模型:

$participant = Participant::find(1);
Event::whereHasRelated($participant)->first(); // guess relationship based on class name and get id from model instance
[OOT]

有点奇怪,但这个问题是我的问题中最接近的话题

下面是一个示例,如果您想显示所有参与者都满足特定要求的事件。比如说,所有参与者都已全额付款的活动。因此,它不会返回一个或多个参与者未全额付款的活动

只需使用其他两种状态的
whereDoesntHave

假设这些状态是完全没有支付[eq:1],支付了部分[eq:2],完全支付[eq:3]

Event::whereDoesntHave('participants', function ($query) {
   return $query->whereRaw('payment = 1 or payment = 2');
})->get();

在Laravel5.8-7.x上测试,对于Laravel8,请使用此选项

Event::whereHas('participants', function ($query) {
     $query->where('user_id', '=', 1);
})->get();

这将返回仅与用户id为1的partcipats具有该事件关系的事件,

例外情况是什么?以帮助读者理解:这将返回参与者用户id为1的事件。如果参与者的用户ID不为1,则事件将不会返回。非常抱歉。我只是弄糊涂了,把评论发错了thread@ChuckLeButt你的评论应该在这个答案中编辑。你的评论很有价值。@DerkJanSpeelman是的,我现在已经补充了。谢谢。为了帮助读者理解:与其他答案不同,这将返回所有事件,无论参与者的用户ID是否为1,但仅在参与者ID为1时才包含参与者对象。我喜欢的是,您仍然可以获得关系对象,如
Event::with(['particients,avenue])
什么应该是$someId值?@fernandotores
$someId
是另一个变量,您不能直接在该函数中使用它,因此您需要传入
使用(…
方法。
Event::whereDoesntHave('participants', function ($query) {
   return $query->whereRaw('payment = 1 or payment = 2');
})->get();
Event::whereHas('participants', function ($query) {
     $query->where('user_id', '=', 1);
})->get();