Scoping/ Объединение коллекций и упорядочение их (Gem Public Activity на рельсах 4)

Я использую Public Activity Gem для создания системы уведомлений. Перед тем, как заявить о своей проблеме, я предоставлю соответствующий код:

Действие контроллера для Деятельности:

 def index
    @activities1 = PublicActivity::Activity.where(owner_id: current_user.articles, owner_type: "Article" )
    @activities2 = PublicActivity::Activity.where(owner_id: current_user.id , owner_type: "User")
    @activities  = @activities1 + @activities2
    @activities.sort_by{ |a| a[:created_at] }
  end

Вид для деятельности # указатель

<% @activities.each do |activity| %>
   <%= render_activity activity %>
<% end %>

Моя цель - собрать коллекцию всех соответствующих действий, которые я хочу отобразить в представлении индекса. Однако происходит нечто подобное:

1) Activity filler text(Created June 1) (Owner: Article)
2) Activity filler text (Created June 3) (Owner: Article)
3) Activity filler text (Created June 4) (Owner: Article)
4) Activity filler text (Created June 1) (Owner: User)
5) Activity filler text (created June 2) (Owner: User)

Сначала отображаются действия с владельцем статьи, затем после этого выполняются действия с владельцем пользователя. Я хотел бы, чтобы они отображались по порядку (:creation_at) и предпочтительно по убыванию, несмотря на то, какой у них тип владельца. Есть ли лучший способ добиться этого?

1 ответ

Решение

Вы можете объединить два запроса в один запрос и позволить базе данных выполнить сортировку.

Что вам нужно, это сделать OR запрос.

Если вы используете Rails 5 (бета или rc), вы можете использовать or способ достижения этого:

PublicActivity::Activity.where(owner_id: current_user.articles, owner_type: "Article" ).
  or(PublicActivity::Activity.where(owner_id: current_user.id , owner_type: "User")).order(id: :desc)

Если вы используете более старую версию Rails, вы можете использовать мощные Arel сделать Or запрос. В вашем случае вот код:

PublicActivity::Activity.where(article_activities.or(user_activities)).order(:id, :desc)

def arel_table
  PublicActivity::Activity.arel_table
end

def article_activities
  arel_table[:owner_id].in(current_user.acticles.map(&:id)).
    and(arel_table[:owner_type].eq("Article"))
end

def user_activities
  arel_table[:owner_id].eq(current_user.id).
    and(arel_table[:owner_type].eq("User"))
end

Вы можете рефакторинг это к вашему PublicActivity::Activity модель.

Другие вопросы по тегам