Search code examples
laraveleloquentlaravel-3

Laravel 3 eloquent many-to-many relationship


I have a Post model and a Tag model into a many-to-many relationship.

When I get the posts and all tags the post have I use this and it works just fine :

$posts = Post::with(array('tags'))
            ->where('cat_id', '=', $cat->id)
            ->where_published(1)
            ->order_by('created_at', 'desc')
            ->paginate('10');

The above code shows the latest posts created and paginate them.

I want to achive the same thing but the other way, to start from the tag and get a list of the posts paginated and ordered by created_at column.

Tag::with(array('posts'))
                ->where('tagname', '=', $tag)
                ->first();

This works but shows all posts, and I want them paginated, ordered and filtered where_published(1).

Can this be done with eloquent using eager loading (without eager loading I already know to do it but there will be too many queries made) ?

Where can I put the filtering and how to get them paginated ?


Solution

  • You can do this:

    Tag::with(array('posts' => function ($query) {
        $query->where('published', '=', 1);
    })->where('tagname', '=', $tag)
    ->first();
    

    However, that's pretty much all you can do with it unfortunately. Ordering and most other stuff is not supported as of yet - the way I got around this was to create a function in the model like so:

    public function posts_ordered()
    {
        return $this->has_many_and_belongs_to('Post')->order_by('your_field', 'asc');
    }
    

    So you will have a normal function for posts() in the model, but also posts_ordered can be used like:

    Tag::with('posts_ordered')->where('tagname', '=', $tag)->first();

    Unfortunately you cannot pass variables (as far as I have tried) to those functions, hence the need to create seperate ones.