Laravel从查询雄辩结果中排除当前id

时间:2016-06-10 00:23:49

标签: php mysql laravel eloquent

我对laravel相当新,我建立了一些“类似的帖子”部分。所以每个帖子都有一个标签,我查询当前标签中的所有id。然后我发现所有的帖子都是id的。现在我的问题是,当前的帖子总是包含在内。查询时是否有一种简单的方法可以排除当前的id?

我似乎无法在laravel docs网站上的帮助函数中找到任何内容

这是我的功能:

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]);
   }

2 个答案:

答案 0 :(得分:2)

解决问题的一种简单方法是直接使用Relationship方法,而不是按属性引用它,您可以像任何雄辩的交易一样添加其他过滤器。

换句话说,您需要替换它:

Tag::find($tag_ids)->projects

有了这个:

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

其中$id是当前项目的ID。这背后的原因是,通过使用方法projects(),您直接引用模型的定义Relationship(最可能是BelongsToMany,根据您的代码判断)可以用作查询构建器(就像任何扩展laravel自己的Eloquent\Model的模型实例)。

您可以在此处找到有关laravel关系以及Query Builder如何工作的更多信息:

但是,您处理它的方式可能会导致一些问题。

从您的代码中我可以假设ProjectTag之间的关系是多对多关系,这可能会导致共享多个标记的项目出现重复结果(正如用户 Ohgodwhy 所述)。

在这种情况下,最好使用laravel的whereHas()方法,它允许您根据模型关系中的条件直接过滤结果(您可以在我提供的链接上找到有关其如何工作的更多信息对于雄辩的关系)。您必须执行以下操作:

// 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();

这样您就可以排除当前项目,同时避免在结果中出现任何重复项。

答案 1 :(得分:1)

我不认为$file = APPPATH . 'third_party/mods/mods_test.xml'; $x = simplexml_load_file($file); echo $x->file['name']; 是一个很好的方法。原因是多个标签可能属于一个项目,你最终会收到大量重复的项目查询,导致性能不佳。

相反,您应该找到不是现有项目的所有项目。这很容易。

Tag::find($tag_ids)->projects

此外,您可以使用$related_projects = Project::whereNotIn('id', [$project->id])->with('tags')->get(); Dependency Injection来改进代码,以确保自动为您提供模型,而不是自己查询。

Route Model Binding

然后将您的路线改为这样的路径(用您的控制器替换您的控制器名称:

public function show(Project $project)

现在Route::get('/projects/{project}', 'ProjectController@show'); 功能中始终可以使用$project,您只需要包含show(在"上面带有"语句中执行)