如何使用一个SQL查询在Laravel(Eloquent)中获取两个相关对象

Mar*_*ski 5 laravel eloquent

我试图在Laravel中根据文档使用预先加载来获取两个相关对象.

https://laravel.com/docs/5.4/eloquent-relationships#eager-loading

我的模特是:

class Lead extends Model {
  public function session() {
    return $this->hasOne('App\LeadSession');
  }
}

class LeadSession extends Model {
  public function lead() {
    return $this->belongsTo('App\Lead');
  }
}
Run Code Online (Sandbox Code Playgroud)

我想通过一个SQL查询获取两个对象.基本上我想执行:

select * from lead_sessions as s 
inner join lead as l 
on l.id = s.lead_id 
where s.token = '$token';
Run Code Online (Sandbox Code Playgroud)

然后能够访问LeadSession和Lead对象.这是我正在尝试的PHP代码:

$lead = Lead::with(['session' => function ($q) use ($token) {
  $q->where('token','=',$token);
}])->firstOrFail();

print($lead->session->id);
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

$lead = Lead::whereHas('session', function($q) use ($token) {
  $q->where('token','=',$token);
})->firstOrFail();

print($lead->session->id);
Run Code Online (Sandbox Code Playgroud)

$session = LeadSession::with('lead')->where('token',$token)->firstOrFail();

print($session->lead->id);
Run Code Online (Sandbox Code Playgroud)

在所有这三种情况下,我都会执行两个查询,一个用于leads表,另一个用于lead_sessions表.

在Eloquent中这样的事情是否可能?在我看来,它应该是一个标准的ORM操作,但由于某种原因,我正在努力一整天.

我不想使用查询生成器,因为我想在之后使用Eloquent对象及其函数.

我来自Python和Django,我想select_related在Django中复制函数的行为.

Edd*_*ove 2

尝试一下,看看它是否会发出多个查询

$session = LeadSession::join('leads', 'leads.id', '=', 'lead_sessions.lead_id')
->where('token',$token)
->firstOrFail();
Run Code Online (Sandbox Code Playgroud)

我希望它只运行一个查询。我没有测试这个。不确定是否需要添加 aselect()来选择列。但是,是的,先尝试一下。

更新 仅添加如何使用会话和潜在客户数据。尝试选择并指定您需要的数据。原因是,如果两个表都有类似的列(例如“id”),其中之一将被覆盖。所以你必须给你的选择加上别名

$session = LeadSession::join('leads', 'leads.id', '=', 'lead_sessions.lead_id')
->where('token',$token)
->select(
    'lead_sessions.*',
    'leads.id as lead_id',
    'leads.name',
    'leads.more_stuff'
)
->firstOrFail();
Run Code Online (Sandbox Code Playgroud)

现在所有这些数据都属于$session变量。为了测试你正在做的事情

print($lead->session->id);
//becomes 
print($session->lead_id); //we aliased this in the query
Run Code Online (Sandbox Code Playgroud)