如何用Eloquent实现这个复杂的查询?

时间:2018-06-24 11:26:17

标签: laravel eloquent

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

$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]上调用未定义的关系[注册]”。

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

表结构和示例可以更好地说明上下文:

例如,有一个具有两种注册类型(rt1和rt2)的会议“会议1”。目前,在“会议1”会议中只有两个注册。一次注册由杰克(Jake)完成,另一次由本(Ben)完成。杰克向3位参与者(他,简和保罗)进行了注册。本只为他做一个注册。表格结构如下。

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

Conferentes表:

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');
}

2 个答案:

答案 0 :(得分:0)

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

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

还请注意,您不需要显式加载每个关系。当您渴望加载嵌套关系时,会自动加载高阶关系。

答案 1 :(得分:0)

根据您的模式,模型定义应该看起来像

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

考虑到您的会议模型上方,还应具有以下映射

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