【问题标题】:How to achieve this complex query with Eloquent?如何用 Eloquent 实现这个复杂的查询?
【发布时间】:2018-12-03 04:51:09
【问题描述】:

我在下面有这个查询来获取在特定会议中注册的所有用户的电子邮件。

$users = User::whereHas('registrations', function ($query) use($conferenceID) {
    $query->where('conference_id', '=', $$conferenceID);
})->get();

dd($users) 显示array:2 [▼ 0 => "....mail.com" 1 => "....mail.com"]。所以它工作正常。

但我只想获取在特定会议 ($conferenceID) 中注册的用户的电子邮件,并且此注册有 1 个或多个与特定注册类型相关联的参与者。

您知道如何正确实现此查询吗?我有下面的代码,但它显示“调用模型 [App\Conference] 上的未定义关系 [Registration]”。

$getEmailsOfAspecificRegistrationType = 
 Conference::with('registrations', 
 'Registration.registrationTypes', 'Registration.registrationTypes.participants')
->where('id', $id)->get();

表格结构和示例以更好地解释上下文:

例如,有一个会议“会议 1”,它有两种注册类型(rt1 和 rt2)。目前,“会议 1”只有两个注册。一个注册由 Jake 完成,另一个由 Ben 完成。 Jake 与 3 名参与者(他、Jane 和 Paul)进行了注册。本只为他做了一个登记。表格结构如下。

我只想获取在会议中注册的用户的电子邮件,ID 为“1”,并且此注册有 1 个或多个与特定注册类型相关联的参与者,例如“rt01”。因此,在这种情况下,我只想获取用户 1“jakeemailtest”的电子邮件,因为它是唯一进行与注册类型“rt01”相关联的注册的参与者,因为参与者 Jake 和 Jane 与此注册类型相关联(尽可能检查参与者表)。

会议桌:

id         name
1            Conference 1

用户表:

id           name           email
1             Jake            jakeemailtest@test...
2             Ben             benmailtest@test...

注册类型表:

id   name     conference_id
1    rt1          1
2    rt2         1

参与者表:

id     registration_id      registration_type_id      name        
1         1                        1                   Jake 
2        1                        1                    Jane
3        1                       2                     Paul
4        2                      2                      Ben         

还有注册表:

id   status                user_that_did_registration       conference_id 

1         Incomplete            1                                     1
2        Incomplete             2                                     1

问题的相关模型:

用户模型:

public function registrations(){
    return $this->hasMany('App\Registration','user_that_did_registration');
}

注册模式:

// user that did the registration
public function customer(){
    return $this->belongsTo(User::class, 'user_that_did_registration', 'id');
}
 public function participants(){
    return $this->hasMany('App\Participant');
}

public function conference(){
    return $this->belongsTo('App\Conference');
}

会议模型:

 public function registrations(){
    return $this->hasMany('App\Registration', 'conference_id');
}

参与者模式:

public function registration(){
    return $this->belongsTo('App\Registration');
}

public function registration_type(){
    return $this->belongsTo('App\RegistrationType');
}

【问题讨论】:

  • 你的模型是如何相互关联的,你可以包括你的模型定义吗?
  • 谢谢,我用模型更新了问题,还用表格结构的例子更新了问题。

标签: laravel eloquent


【解决方案1】:

根据您的架构,您的模型定义看起来应该是这样的

  • 用户有注册 => 注册属于用户
  • Registration has Participants => 参与者属于Registration
  • 注册类型有参与者=>参与者属于注册类型
  • 会议有注册类型 => 注册类型属于会议
  • 会议有注册 => 注册属于会议

考虑到您的会议模型还应该有以下映射

public function registration_types(){
    return $this->hasMany('App\RegistrationType', 'conference_id');
} 

您可以通过以下方式获得所需的用户

$users = User::whereHas('registrations.participants.registration_type', function ($query) use ($conference_id, $request) {
                $query->where('name', '=', $request->rype)
                      ->where('conference_id', '=', $conference_id);
            })->whereHas('registrations', function ($query) use ($conference_id) {
                $query->where('conference_id', '=', $conference_id);
            })->get(); // use pluck('email') instead of get to select only email

【讨论】:

  • 谢谢,你知道如何在 "$query->where('name', '=', 'rt1')" 中使用 "$request-" 代替静态值 "1" >rtype”?因为它显示为 $query->where('name', '=', $request->rype)" 的未定义变量。但也将 $request->type 添加到 use() 中,如 use($conference_id, $request ->rtype)" 它显示为 "Expected: )"。
  • @John 查看更新的答案以在闭包函数中使用 $request
  • 查询返回一个空集合“Collection {#289 ▼ #items: [] }”。
  • 在会议模型中,我有registrationTypes()而不是registration_types(),例如:“public function registrationTypes(){ return $this->hasMany('App\RegistrationType', 'conference_id'); } " 而不是 "public function registration_types(){ return $this->hasMany('App\RegistrationType', 'conference_id'); } "。但是改成registration_types()也会出现一个空集合。
  • 谢谢,问题似乎在于您的查询中有“ $query->where('name', '=', $request->rype)” 但 $request-> rtype 返回注册类型的 id,更改为 name 而不是 id 像 " $query->where('id', '=', $request->rype)" 有效。
【解决方案2】:

您指定了错误的关系名称。您在with() 方法中提供的字符串应与模型上的关系方法名称匹配。渴望加载关系的正确方法是:

$getEmailsOfAspecificRegistrationType = Conference::with(
    'registrations.participants'
) ->where('id', $id)->get();

另外请注意,您不需要显式加载每个关系。当您急切加载嵌套关系时,会自动加载更高阶的关系。

【讨论】:

  • 谢谢,但这样会出现“调用模型 [App\Registration] 上的未定义关系 [registration_type]。”。
  • 糟糕!看起来您在注册模型上有参与者关系。您可以直接在registerations 上调用此关系,而无需加载registration_type。我已经更新了我的答案
猜你喜欢
  • 2014-04-27
  • 2018-02-02
  • 2015-12-06
  • 2021-11-16
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多