Michael
Michael

Reputation: 141

Accessing Properties Through Relationships in Laravel 5.0

I have several models set up in a Grandparent -> Parent -> Child relationship, where each has a one-to-many relationship with the one beneath it. The backend is set up through migrations using the default created_at and modified_at dates, relevant as that is what I'm trying to grab records by.

I currently have (names replaced):

$parent->child->where('created_at', '=', $date);

Through echo'ing it out I can verify that $date is correct when the where function is run, and matches records in the database. My expectation based on documentation is that this should return a Collection. When I attempt to iterate through it to get each instance of the model inside, however, I get errors saying I'm attempting to access properties of a non-object. (Just trying to echo out the created_at date).

I also tried putting ->first() after the original, with the assumption that it would spit out the first child as an object, that matched those pre-requisites, however it comes out null despite the collection not showing as null when similarly tested.

My question is, is there a way to get the first() approach to work, returning a single instance of the model? Similar to:

$parent->child->where('created_at', '=', $date)->first();

This is my first time posting a question so if you need more info just ask.

Upvotes: 2

Views: 1169

Answers (2)

patricus
patricus

Reputation: 62228

The issue you're having is due to the difference between:

$parent->child;

and

$parent->child();

The former ($parent->child) is a Collection of all the child objects, whereas the latter ($parent->child()) is the relationship query for the child objects.

The sneaky problem you've hit is that both support the where() method, but their parameters are a little different. The parameters you're using would work fine for the where() method on the relationship query, but they are not correct for the where() method on the Collection, which is what you're using.

You either need to switch to using the relationship query, or change your parameters to work with the where() on the Collection:

$children = $parent->child->where('created_at', $date);
// or
$children = $parent->child()->where('created_at', '=', $date)->get();

Note: the where() method on the Collection will filter the collection based on the field name ('created_at') being equal (== or ===) to the $date value. The third parameter will govern the strictness (default is strict (===), or use false for loose (==)).

Upvotes: 3

Patrick Stephan
Patrick Stephan

Reputation: 1829

$parent->child returns the processed query as a collection. To add to the query with your where statement you will need to use the child method (which returns a query object), not the child property:

$parent->child()->where('created_at', '=', $date)->first();

Upvotes: 1

Related Questions