Laravel. Use scope() in models with relation

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Title: Laravel: Effectively Using Scopes with Eloquent Relationships

In the world of Laravel development, you often work with multiple related models. One such instance is having two connected models: Category and Post. The Post model comes equipped with a published() scope method (scopePublished()) that represents posts which are live on your website.

However, when you attempt to retrieve categories along with their associated published posts using the following code:

php
$categories = Category::with('posts')->published()->get();

You may run into an error stating that the published scope is undefined for categories. This occurs because you're trying to apply a scopePublished() method on the Category model, which doesn't have this functionality by default. In order to resolve this issue, let us examine how to properly use scopes with relationship models in Laravel:

  1. Analyze your relations: Review the relationships between Category and Post. The Category model has many posts, while each Post belongs to a single category. We can leverage these relationships for efficient retrieval of data.

  2. Set up the Eloquent relationships: In our example, we have established these relationships as follows:

    php
    class Category extends \Eloquent
    {
     public function posts()
     {
         return $this->HasMany('Post');
     }
    }</li>
    </ol>
    <p>class Post extends \Eloquent<br>{<br>   public function category()<br>   {<br>       return $this->belongsTo('Category');<br>   }</p>
    <p>   public function scopePublished($query)<br>   {<br>       return $query->where('published', 1);<br>   }</p>
    <p>}<br>

    1. Apply the published scope: Since we want to fetch only published posts, we should apply the scopePublished method before retrieving the post data. This can be done by invoking the scope on the query object for Posts using a closure inside the relationship definition of Category:

      php
      class Category extends \Eloquent
      {
       public function posts()
       {
           return $this->HasMany('Post')
                        ->with(['category' => function($query) { $query->published(); }]);
       }
      }

    In this implementation, we added a published scope to the post relationship in the Category model. When retrieving posts related to a specific category, the query will include the published scope in order to only return the published posts.

    1. Retrieve all categories with their associated published posts: Now that we've defined and applied the scopePublished, we can use it to retrieve all categories along with their respective published posts:

      php
      $categories = Category::with('posts')->get();

    This will result in an array of category objects each containing the details related to its published posts.

    In conclusion, when working with relationship models and scopes in Laravel, it is important to understand how to apply these methods efficiently. By correctly setting up our relationships and applying the scopePublished method as needed, we can effectively use scopes with Eloquent relations, ensuring cleaner code and better performance.