Laravel 具有预加载关系的模型
Laravel model with preloaded relation
我有一个数据库 table 用于存储我的职位以便不重复它们,并且 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();
给出错误,知道这是如何完成的吗?
当通过方法 $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();
load()
在查询执行后执行。它被称为 lazy-loading。预加载正在使用 with()
.
预加载通常比延迟加载快(我在这一点上可能是错的,如果我错了请纠正我)。
此外,使用 jobs()
或任何其他关系,这将 return 关系 object 本身,而通过 ->Jobs
访问它时将执行关系查询并将return一个collection(如果有很多)或模型(如果有一个)。
$personJobs = Person::find(1)->jobs()->load('title')->get();
不起作用的原因是因为您本质上是在说“作业 hasMany 关系将加载“标题”,但它不起作用,因为 hasMany
没有load()
函数。
所以如果你想解决这个问题,你可以Person::with('jobs.title')->find(1)
或者Person::find(1)->load('jobs.title')
始终使用内部预加载 JobTitles 的工作模型。您可以在工作模型中添加 $with
属性:
class Job extends Model
{
use Notifiable;
protected $with = ['title'];
}
我有一个数据库 table 用于存储我的职位以便不重复它们,并且 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();
给出错误,知道这是如何完成的吗?
当通过方法 $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();
load()
在查询执行后执行。它被称为 lazy-loading。预加载正在使用 with()
.
预加载通常比延迟加载快(我在这一点上可能是错的,如果我错了请纠正我)。
此外,使用 jobs()
或任何其他关系,这将 return 关系 object 本身,而通过 ->Jobs
访问它时将执行关系查询并将return一个collection(如果有很多)或模型(如果有一个)。
$personJobs = Person::find(1)->jobs()->load('title')->get();
不起作用的原因是因为您本质上是在说“作业 hasMany 关系将加载“标题”,但它不起作用,因为 hasMany
没有load()
函数。
所以如果你想解决这个问题,你可以Person::with('jobs.title')->find(1)
或者Person::find(1)->load('jobs.title')
始终使用内部预加载 JobTitles 的工作模型。您可以在工作模型中添加 $with
属性:
class Job extends Model
{
use Notifiable;
protected $with = ['title'];
}