具有预加载关系的 Laravel 模型
Posted
技术标签:
【中文标题】具有预加载关系的 Laravel 模型【英文标题】:Laravel model with preloaded relation 【发布时间】:2021-07-19 02:38:32 【问题描述】:我有一个数据库表来存储我的职位,以免重复它们,并且 Job 模型在内部具有关系,所以当我使用 Eloquent 模型时,我必须总是一遍又一遍地调用或加载 JobTitles 模型。有没有办法始终使用内部预加载 JobTitles 的 Job Model?
class Job extends Model
use Notifiable;
protected $fillable = [ ... ];
protected $hidden = [
'token',
];
public function title()
return $this->belongsTo('App\Models\JobTitle','job_title_id');
public function people()
return $this->belongsToMany('App\Models\Person','job_person','job_id','person_id');
这是 JobTitle 模型
class JobTitle extends Model
use Notifiable;
protected $table = "job_titles";
protected $primaryKey = 'job_title_id';
protected $fillable = [
'name',
];
protected $hidden = [
'token',
];
public function jobs()
return $this->hasMany('App\Models\Job','job_title_id');
现在我在控制器中的代码如下所示:
$job = Job::all()->load('title');
它工作正常,但是当我从人们那里调用工作时
$personJobs = Person::find(1)->jobs()->load('title')->get();
报错,有什么办法吗?
【问题讨论】:
不是'title'而不是'title'吗? @codeninja 是的,我刚刚纠正了它,但这不是问题 【参考方案1】:当通过 $person->jobs()
方法调用关系时,您最终会得到一个查询构建器,因此您不能调用像 load()
这样的模型方法,因为您没有模型的实例。
在获得第一个结果之前调用关系会更有效 (nested eager loading)
$person = Person::with('jobs.title')->find(1);
$personJobs = $person->jobs;
如果您不想从数据库中查询人员数据,您应该使用 whereHas
$personJobs = Job::whereHas('people', function($personQueryBuilder)
$personQueryBuilder->where('id',1);
)->with('title')->get();
【讨论】:
【参考方案2】:load()
在查询执行后执行。这称为延迟加载。急切加载使用with()
。
急切加载通常比延迟加载快(我可能在这个上错了,如果我错了,请纠正我)。
此外,使用jobs()
或任何其他关系,这将返回关系对象本身,而通过->Jobs
访问它将执行关系查询并返回一个集合(如果有的话)或模型(如果有的话)。
$personJobs = Person::find(1)->jobs()->load('title')->get();
不起作用的原因是因为您本质上是在说“工作 hasMany 关系将加载不起作用的“标题”,因为hasMany
没有load()
功能。
所以如果你想解决这个问题,你可以做Person::with('jobs.title')->find(1)
或Person::find(1)->load('jobs.title')
【讨论】:
Person::with('jobs.title')->find(1)
也给了我个人数据
@HydyrAvezberdiyew 在这种情况下,使用$personsJobs = Person::find(1)->Jobs->load('title')
;
但是你建议使用 with(),不是吗? @杰里米
@HydyrAvezberdiyew 问题可以通过加载或使用来解决,只是知道使用哪个以及在哪里使用它。
@HydyrAvezberdiyew 个人,我尽量使用 with() 。我通常在条件上使用 load()。如果在任何情况下都会对整个函数使用某些东西,那么我使用 with()【参考方案3】:
始终使用内部预加载 JobTitles 的作业模型。你可以在你的工作模型中添加$with
属性:
class Job extends Model
use Notifiable;
protected $with = ['title'];
【讨论】:
是的,我也使用过 $with,在官方文档中找到。但是忘了回答我的问题谢谢。以上是关于具有预加载关系的 Laravel 模型的主要内容,如果未能解决你的问题,请参考以下文章