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
модель.