Laravel Eloquent 查询关系

Laravel Eloquent query with relation

在 Laravel 环境 (v 5.7) 中,我有两个表:filmsversions 在 1 中相关模型中定义的许多关系如下:

class Film extends Model {
    ...
    public function versions() {
        return $this->hasMany(Version::class);
    }
}
class Version extends Model {
    ...
    public function film() {
        return $this->belongsTo(Film::class);
    }
}

我想选择一个电影的随机版本 及其相关的父电影 ,所以在控制器中我这样做:

...
use App\Film;
use App\Version;

class HomeController extends Controller {
    ...
    public function index() {
        $rndVersion = Version::inRandomOrder()->first();
        $relatedFilm = $rndVersion->film->first();

一切正常,除了 返回的 film 始终是整个记录集的第一个,而不是 version 我之前从数据库加载的。

我试图通过以下方式检索所有内容:

$rndVersion = Version::inRandomOrder()->with('film')->first();

它可以工作,但是它将所有内容打包到存储在 $rndVersion 中的单个对象中,我宁愿将两者分开。

那么,我做错了什么? 我通常应该怎么做才能获得 selected/loaded 一个的父记录?

提前致谢。

我发现了问题...

调用模型中定义的关系方法的方式会改变返回的结果。

一般来说,如果您拨打:

$model->relationship() //with parenthesis

关系实例被返回。您将该方法作为方法调用,并且对于 Eloquent 模型 classes,它 "serves as powerful query builder" 和 "provides powerful method chaining and querying capabilities" (see here).

否则如果你调用:

$model->relationship //without parenthesis

您会直接获得集合的实例。通过这种方式,您可以将方法作为 属性 调用并获得 Laravel Collection,从而让您在集合上循环,获取记录(模型)属性并使用集合 class 的所有方法。

所以,就我而言,写作

$rndVersione = Version::inRandomOrder()->first();
$rndFilm = $rndVersione->film()->first(); //film() WITH parenthesis

有效,我猜是因为 first() 方法是作为一种方法在关系上调用的,因此保持了查询构建的正确性。