Correctly using Eloquent relationships

Submitted by chadwithuhc - 3 years ago

I spent a good hour trying to figure out why my Eloquent relationship wasn't working when I found out it was because of the difference between `$model->relationship->value` and `$model->relationship()->value`.

/**
 * Using without function call means to get relationship values
 */

// RIGHT
// When you want to access the relationship values, use without function call
User::find(1)->role->name;
// Calling methods for shorthand checks
//   Assuming `isAdmin() = return $this->name === 'admin'`
User::find(1)->role->isAdmin();

// WRONG
// Throws "Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name"
User::find(1)->role()->name;
// Throws "Call to undefined method Illuminate\Database\Query\Builder::isAdmin()"
User::find(1)->role()->isAdmin();


/**
 * Using with function call means to continue using Query Builder
 */

// RIGHT
// Filter down a users posts in a specfic category (Don't forget the `->get()`)
User::find(1)->posts()->where('category', '=', 'Eloquent')->get();
// Calling methods that use the Query Builder
//   Assuming `recentPosts() = return $this->where('posted_at', '>', /* Today - x days */)`
User::find(1)->posts()->recentPosts()->get();

// WRONG
// Throws "PHP Fatal error:  Call to undefined method Illuminate\Database\Eloquent\Collection::where()"
User::find(1)->posts->where(...)->get();
// Throws "PHP Fatal error:  Call to undefined method Illuminate\Database\Eloquent\Collection::recentPosts()"
User::find(1)->posts->recentPosts()->get();
comments powered by Disqus

Ads cover the costs of maintaining Laravel-tricks