Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel exclude current id from query eloquent results

I am fairly new to laravel and I built a little "similar posts" section. So every post has a tag and I query all the id's from the current tag. And then I find all the posts with thoses id's. Now my problem is that the current post is always included. Is there an easy way to exclude the current id when querying?

I can't seem to find anything in the helper function on the laravel docs site

this is my function:

public function show($id)
    {
       $project = Project::findOrFail($id);

        foreach ($project->tags as $tag){
            $theTag = $tag->name;
        }

        $tag_ids = DB::table('tags')
            ->where('name', "=", $theTag)
            ->value('id'); 

        $similarProjects = Tag::find($tag_ids)->projects;

       return view('projects.show', ['project' => $project, 'similarProjects' => $similarProjects]);
   }
like image 409
Cruzito Avatar asked Feb 06 '23 20:02

Cruzito


1 Answers

An easy way to solve your issue would be to use the Relationship method directly instead of referring to it by property, which you can add additional filters just like any eloquent transaction.

In other words, you would need to replace this:

Tag::find($tag_ids)->projects

With this:

Tag::find($tag_ids)->projects()->where('id', '!=', $id)->get()

Where $id is the current project's id. The reason behind this is that by using the method projects(), you are referring your model's defined Relationship directly (most probably a BelongsToMany, judging by your code) which can be used as a Query Builder (just as any model instance extending laravel's own Eloquent\Model).

You can find more information about laravel relationships and how the Query Builder works here:

  • https://laravel.com/docs/5.1/eloquent-relationships
  • https://laravel.com/docs/5.1/queries

However, the way you are handling it might cause some issues along the way.

From your code i can assume that the relationship between Project and Tag is a many to many relationship, which can cause duplicate results for projects sharing more than 1 tag (just as stated by user Ohgodwhy).

In this type of cases is better to use laravel's whereHas() method, which lets you filter your results based on a condition from your model's relation directly (you can find more info on how it works on the link i provided for eloquent-relationships). You would have to do the following:

// Array containing the current post tags
$tagIds = [...];

// Fetch all Projects that have tags corresponding to the defined array 
Project::whereHas('tags', function($query) use ($tagIds) {
    $query->whereIn('id', $tagIds);
})->where('id', !=, $postId)->get();

That way you can exclude your current Project while avoiding any duplicates in your result.

like image 99
EricDS Avatar answered Feb 10 '23 06:02

EricDS