145

I have two related models: Category and Post.

The Post model has a published scope (method scopePublished()).

When I try to get all categories with that scope:

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

I get an error:

Call to undefined method published()

Category:

class Category extends \Eloquent
{
    public function posts()
    {
        return $this->HasMany('Post');
    }
}

Post:

class Post extends \Eloquent
{
   public function category()
   {
       return $this->belongsTo('Category');
   }


   public function scopePublished($query)
   {
       return $query->where('published', 1);
   }

}

1 Answer 1

255

You can do it inline:

$categories = Category::with(['posts' => function ($q) {
  $q->published();
}])->get();

You can also define a relation:

public function postsPublished()
{
   return $this->hasMany('Post')->published();
   // or this way:
   // return $this->posts()->published();
}

and then:

//all posts
$category->posts;

// published only
$category->postsPublished;

// eager loading
$categories->with('postsPublished')->get();
Sign up to request clarification or add additional context in comments.

5 Comments

Incidentally, if you want to ONLY get where you have published posts: Category::whereHas('posts', function ($q) { $q->published(); })->get();
@tptcat yes. Also can be Category::has('postsPublished') in this case
Clean question, clean answer!
What if the query scope has a parameter?
This solution is very clean rather than pass an ugly function after array key 'with' method

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.