Laravel - 在多对多关系中急切加载单个项目

djt*_*djt 4 php laravel

在 Laravel 中,是否可以从BelongsToMany关系中急切加载“第一个”项目?比如,Item从那个关系中返回一个,而不是一个Collection

从我试图(和读取)申请first()limit('1')或任何其他约束不会返回单个项目

Jar*_*zyk 5

使用存取器

我想你需要像latest,first或这样的集合中的单个项目,所以你可以这样做:

public function items()
{
  return $this->belongsToMany(Item::class);
}

public function getLatestItemAttribute()
{
  return $this->items->sortByDesc('created_at')->first();
}
Run Code Online (Sandbox Code Playgroud)

那么你可以简单地使用:

$yourModel->latestItem; // single related model OR null
Run Code Online (Sandbox Code Playgroud)

编辑:正如@Hkan 在评论中提到的,上面的代码将导致获取整个集合并对其进行处理。也就是说,您可以交替使用关系对象并直接查询表:

public function getLatestItemAttribute()
{
  return $this->items()->latest()->first();
}
Run Code Online (Sandbox Code Playgroud)

但是,这样您就可以在每次调用时运行查询$model->latestItem。因此,您将获得模型的新副本,而不是同一个实例,显然您可以根据您的用例查询数据库任意次数。

困难但最好的方法是模仿这种关系:

public function getLatestItemAttribute()
{
  if (!$this->relationLoaded('latestItem')) {
    $this->setRelation('latestItem', $this->items()->latest()->first());
  }

  return $this->getRelation('latestItem');
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,一旦加载,就会$model->latestItem像任何其他单一关系一样对待。也就是说,无论何时调用访问器,它将是单个实例,并在使用push方法时保存。