Сортировка микросообщений по количеству комментариев (Rails)? - PullRequest
1 голос
/ 31 января 2012

У меня есть 2 модели: Микросообщения (который has_many :comments) и Комментарии (который belongs_to :micropost).

В следующем представлении:

views / 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

Iудалось получить количество комментариев для каждого микросообщения:

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

Как отсортировать микросообщения по количеству комментариев?

Есть предложения для этого?

Ответы [ 2 ]

3 голосов
/ 31 января 2012

Вы можете делать глупую сортировку, считая комментарии для каждого микросообщения, но это не очень хорошая идея. Потому что каждый раз, когда ваше действие индекса вызывается, rails будет выполнять N + 1 запросов к базе данных, где N - количество микросообщений.

Лучшее решение здесь - использовать функцию Rails counter_cache. Это отдельный столбец в вашей таблице базы данных микросообщений, где хранится количество комментариев. Кроме того, он обновляется автоматически каждый раз, когда вы создаете новый или удаляете комментарий.

Во-первых, вам нужно добавить столбец в вашу базу данных. Для этого создайте миграцию примерно так: add_column :microposts, :comments_count, :integer, :default => 0, :null => false

После этого измените код в вашей модели комментариев на что-то вроде этого: belongs_to :micropost, :counter_cache => true

После всех этих изменений ваш столбец comments_count в микросообщении будет увеличиваться при каждом создании нового комментария и уменьшаться при каждом удалении комментария. Кроме того, вы можете сортировать микросообщения по значению этого столбца, например так:

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

1 голос
/ 31 января 2012

Вы можете создать метод в micropost.rb и отсортировать его по виртуальному атрибуту:

def comments_count
  comments.count
end

Затем сортируйте свою коллекцию методом sort_by:

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

Кроме того, вы можете использовать метод reverse, если вам нужно обратное направление сортировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...