Rails开发:如何从关联文章搜索结果中排除当前文章?
解决关联文章排除当前文章的问题
嘿,这个场景我太熟悉了!要从关联文章列表里移除当前展示的文章,最优方案是在数据库查询阶段就完成过滤,也就是用Active Record的where.not()方法,这比在Ruby层面用!=筛选要高效得多。我来一步步给你讲清楚:
1. 修改控制器代码(核心改动)
你原来的show方法里直接查询了所有文章,现在只需要在查询时加上排除当前文章的条件即可:
# posts_controller.rb 的 show 方法 def show @post = Post.friendly.find(params[:id]) # 关键改动:用 where.not 排除当前文章的id,再按分类分组 @related = Post.friendly.where.not(id: @post.id).group_by(&:blog_category_id) end
2. 为什么选where.not()而不是!=?
这里有个性能和效率的核心区别:
where.not()是数据库层面筛选:它会把过滤条件转换成SQL的WHERE id != ?语句,数据库只返回排除当前文章后的记录,内存占用小,查询速度快,尤其是文章数量多的时候优势明显。- Ruby层面的
!=(比如用reject):如果写成Post.friendly.all.reject { |p| p.id == @post.id }.group_by(...),会先把所有文章加载到Ruby内存里,再逐一筛选,数据量大时会拖慢页面加载速度,属于低效方案。
3. 视图代码无需改动
你现有的视图代码可以直接继续使用,因为@related已经提前排除了当前文章,遍历@related[@post.blog_category_id]时只会显示同分类下的其他文章:
<% @related[@post.blog_category_id]&.each do |rel| %> <a href="/posts/<%= rel.friendly_id %>" class="img-cont"> <%= image_tag("Index/#{rel.thumbnail_link}", :alt => "#{rel.title}", class: "soundtrack-img top-drop") %> <div class="img-mdl wellington"><h3 class="img-txt basic"><%= rel.title %></h3></div> </a> <% end %>
额外小提示
用id作为排除条件比用friendly_id更可靠,因为主键id是数据库唯一且固定的标识,而friendly_id可能会根据文章标题修改而变化,避免出现筛选失效的情况。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

