barakuda28
barakuda28

Reputation: 2902

How do I take related posts (by category) with Eloquent?

I have a question on how to fetch the related posts of a particular post by category using Eloquent. I know how to do it in pure MySQL but am sure Eloquent will have nicer alternative to it.

My tables are: posts categories post_category (pivot)

I have made the neccessary Eloquent connections, so I want to do something like: $post->categories()->posts()->exclude($post)->get().

Of course this won't work. I get an error on posts() because "Builder doesn't have a method posts()", but hopefully you get the idea. How would you do it with Eloquent?

Upvotes: 2

Views: 1978

Answers (5)

majid behzadnasab
majid behzadnasab

Reputation: 113

if you have multiple category (Pivot ex:RelPortfolioCategory)

Portfolio Model:

public function getCats(){
        return $this->hasMany(RelPortfolioCategory::class,'portfolioID','id');
    }

controller:

public function portfolioDetail($slug){
        $db = Portfolio::where('slug' , $slug)->with('getCats')->firstOrFail();
        $dbRelated = RelPortfolioCategory::whereIn('categoryID' , $db->getCats->pluck('categoryID'))->whereNot('portfolioID' , $db->id)
            ->with('getPortfolioDetail')->get();
        return view('portfolioDetail' , compact('db' , 'dbRelated'));
    }

Upvotes: 0

David Heremans
David Heremans

Reputation: 671

Why don’t you define a ‘relatedposts’ relation where search for posts with the same category id? Then you can simply do $post->relatedposts...

You’re making it overcomplicated imo...

Upvotes: 0

James Allan
James Allan

Reputation: 280

I was trying to get my related posts by category and searched on google and got here. I made this, and it worked fine.

   public function getSingle($slug){
        $post = Post::where('slug', '=', $slug)->first();
        $tags=Tag::all();
        $categories=Category::all();

        $related= Post::where('category_id', '=', $post->category->id)
            ->where('id', '!=', $post->id)
            ->get();

        return view('blog.show')
            ->withPost($post)
            ->withTags($tags)
            ->withCategories($categories)
            ->withRelated($related);         
    }

In my view('blog.show')

$post->title
$post->content

//related posts
@foreach($related as $posts)
  $posts->title
  $posts->category->name
@endforeach

I don't know if this is the right way, but it works for me. I hope this helps someone

Upvotes: 0

IndianAg0711
IndianAg0711

Reputation: 178

One of the confusing parts about Eloquent's relations is that the method on a model that defines the relation will bring back a relation object when called like you're calling it:

$posts->categories();

To return a collection of category models attached to your posts you should use something like this:

Post::find(primary key of post)->categories;

Or get all posts and iterate through the models individually:

$posts = Post::all();

foreach($posts as $post) {
    $post->categories;
}

Here's a resource I found very helpful in learning to use Eloquent's relation methods: http://codeplanet.io/laravel-model-relationships-pt-1/

Upvotes: 0

Marcin Nabiałek
Marcin Nabiałek

Reputation: 111869

It's hard to say what you want to achieve, bot probably you want to get:

Posts::whereIn('id', $post->categories()->lists('id'))->whereNot('id',$post->id)->get();

Upvotes: 1

Related Questions