Rails 5.1:如何通过distinct count展示含相似最少植物成分的金酒?
解决金酒列表重复打印&按最少相似植物成分排序的问题
看起来你已经走在正确的路上了,但当前的问题主要出在查询没有正确统计匹配的植物成分数量,且没有对结果去重排序,导致返回了重复的金酒记录,最终视图里重复打印名称。下面是具体的修复方案:
1. 修正查询逻辑:统计匹配数并按最少匹配排序
你的核心需求是找到与当前金酒(排除自身)拥有最少共同植物成分的其他金酒,所以需要先统计每个金酒和目标金酒的共同成分数量,再按这个数量升序排序,同时确保每个金酒只返回一条记录。
假设你用的是Rails ActiveRecord,调整后的查询代码如下:
# 获取当前展示的目标金酒 target_gin = Gin.find(params[:id]) # 提取目标金酒的所有植物成分ID target_botanical_ids = target_gin.botanicals.pluck(:id) # 查询并排序:找到最少相似成分的金酒 least_similar_gins = Gin.joins(:botanicals) .where.not(id: target_gin.id) # 排除当前金酒 .where(botanicals: { id: target_botanical_ids }) .group('gins.id') # 按金酒ID分组,避免重复 .select('gins.*, COUNT(botanicals.id) AS matching_botanical_count') # 统计共同成分数量 .order('matching_botanical_count ASC') # 按匹配数升序,最少的在前
如果需要包含完全没有共同成分的金酒(这些应该排在最前面),可以把joins换成left_joins:
least_similar_gins = Gin.left_joins(:botanicals) .where.not(id: target_gin.id) .where(botanicals: { id: target_botanical_ids }) .group('gins.id') .select('gins.*, COUNT(botanicals.id) AS matching_botanical_count') .order('matching_botanical_count ASC')
2. 修复视图层的重复打印问题
之前重复打印名称,大概率是因为查询返回了同一金酒的多条记录(每个匹配的植物成分对应一条),或者你在视图中错误循环了植物成分而非金酒列表。
在show页面的视图里,直接循环处理后的least_similar_gins即可:
<h2>Gins with the Least Similar Botanicals</h2> <ul> <% least_similar_gins.each do |gin| %> <li><%= gin.name %> — <%= gin.matching_botanical_count %> shared botanical(s)</li> <% end %> </ul>
问题根源分析
你原来的查询只做了关联筛选,但没有按金酒ID分组去重,也没有统计匹配数量,所以返回的结果是每个金酒对应其匹配的每一种植物成分的记录,自然会在视图中重复打印名称。加上分组、统计和排序后,就能得到符合预期的最少相似金酒列表了。
内容的提问来源于stack exchange,提问作者Simon Cooper
相关产品推荐
相关产品推荐

