按评论数量(Rails)对微博进行排序?

时间:2012-01-31 07:00:27

标签: ruby-on-rails

我有2个模型: Microposts has_many :comments}和评论belongs_to :micropost)。

在以下视图中:

视图/微柱/ index.html.erb:

<h2>Micropost Index</h2>
<% @microposts.each do |micropost| %>
  <h2><%= micropost.title %></h2>
  <p><%= micropost.content %></p>
  <p><%= micropost.comments.count %></p>
  <ul>
    <li><%= link_to 'Show', micropost %></li>
    <li><%= link_to 'Edit', edit_micropost_path(micropost) %></li>
    <li><%= link_to 'Destroy', micropost, confirm: 'Are you sure?', method: :delete %></li>
  </ul>
  <br />
<% end %>

控制器/ microposts.rb:

  def index
    @microposts = Micropost.all
  end

我能够获得每个微博的评论数量:

<p><%= micropost.comments.count %></p>

如何按评论数量对微博进行排序?

有任何建议可以实现这一目标吗?

2 个答案:

答案 0 :(得分:3)

你可以通过计算每个微博的评论来做一个愚蠢的排序,但这不是一个好主意。每次调用索引操作时,rails都会执行N + 1个数据库查询,其中N是微博的数量。

这里最好的解决方案是使用Rails counter_cache功能。它是您的微博数据库表中的一个单独列,其中存储了注释数量。此外,每次创建新评论或删除评论时,它都会自动更新。

首先,您需要向数据库添加一列。为此,请使用以下内容创建迁移: add_column :microposts, :comments_count, :integer, :default => 0, :null => false

之后,将评论模型中的代码更改为: belongs_to :micropost, :counter_cache => true

完成所有这些更改后,每次创建新注释时,micropost中的comments_count列都会递增,每次删除注释时都会递减。此外,您可以按此列的值对微博进行排序,如下所示:

@microposts = Micropost.order('comments_count ASC').all

答案 1 :(得分:1)

您可以在micropost.rb中创建方法,并按虚拟属性排序:

def comments_count
  comments.count
end

然后使用sort_by方法对您的收藏品进行排序:

<% @microposts.sort_by(&:comments_count).map do |micropost| %>
  <%= micropost.title %>
  ...
<% end %>

此外,如果您需要相反的排序方向,则可以使用reverse方法。