0

In a Laravel environment (v 5.7) I've two tables: films and versions related in a 1 to Many relationship defined in Models as so:

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

I want to pick a random Version of a Film and its related parent Film, so in a controller I do this:

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

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

All works fine, except the fact that the returned film is always the first of the entire recordset, and not the parent of the version I previously loaded from the DB.

I've tried to retrieve all together with:

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

and it works, but it packs all in a single object stored in $rndVersion, and I'd rather prefer to keep the two things separate.

So, what am I doing wrong? What shall I generally do to get the parent record of a selected/loaded one?

Thank you in advance.

1 Answer 1

1

I found the issue...

The way you call the relationship method defined in the Model changes the returned result.

In general, if you call:

$model->relationship() //with parenthesis

an instance of the relationship is returned. You are calling the method as a method and, as it is for Eloquent model classes, it "serves as powerful query builder" and "provides powerful method chaining and querying capabilities" (see here).

Otherwise if you call:

$model->relationship //without parenthesis

you get directly an instance of the Collection. This way you are calling the method as a property and getting a Laravel Collection thus letting you loop on the collection, get record (model) properties and use all the methods of the Collection class.

So, in my case, writing

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

works, I guess because the first() method is called on the relationship as a method, therefore maintaining the correctness of query building.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.