0

我不太确定如何命名这个问题,但我会在这里解释。我在 Rails 4 上,我正在尝试构建一个葡萄酒评论应用程序。我有一个葡萄酒模型和一个相关的评论模型..

葡萄酒.rb

has_many :reviews

评论.rb

belongs_to :wine
has_many :taggings
has_many :tags, through: :taggings

我的评论具有通过has_many has_many与单独模型“tagging.rb”的关系制作的标签

标签.rb

has_many :taggings
has_many :reviews, through: :taggings

标记.rb

belongs_to :review
belongs_to :tag

在我的葡萄酒show.html.erb页面上,我显示了所有评论的列表,每条评论都显示了它被标记的内容。我正在尝试计算每个标签在评论中使用的次数,并根据所有评论显示葡萄酒收到的前 5 个标签的列表。我该怎么做?

我可以在我的 review.rb 中获得应用范围内使用过的前 5 个标签的列表

def self.tag_counts
    Tag.select("tags.*, count(taggings.tag_id) as count").
        joins(:taggings).group("taggings.tag_id").order("count DESC").limit(5)
end

但我希望能够将前 5 名用于特定的葡萄酒。谢谢。

更新

感谢@kardeiz 帮助我:)。我最终使用它来获得我正在寻找的结果

Tag.joins(:reviews => :wine).where("wines.id = ?", self.id).group("taggings.tag_id").select("wines.id, tags.*, COUNT(taggings.tag_id) as count").order('count DESC').limit(5)

那么在我看来,我必须@wine.tag_counts.each遍历每个标签。然后每次迭代我都会打印出标签名称和计数。

4

1 回答 1

1

我没有现成的测试数据来确认这项工作,但我认为这是你想要的(为了易读性而拆分):

Tag
  .joins(:reviews => :wine)
  .where('wines.id = ?', whatever_id)
  .group("taggings.tag_id")
  .order("COUNT(taggings.tag_id) DESC")
  .limit(5)

编辑

对不起,我误读了这个问题。我认为这应该做你想要的(虽然我没有测试过):

in_sql = Tag
  .joins(:reviews => :wine)
  .group("taggings.tag_id")
  .select("wines.id as wid, tags.*, COUNT(taggings.tag_id) as count")
  .to_sql

out_sql = %Q{
  select * 
  from (#{in_sql})
  where wid = #{whatever_id}
  order by count
  limit 5
}

ActiveRecord::Base.connection.execute(out_sql)
于 2013-09-12T22:15:28.380 回答