Я не думаю, что есть какой-то особый способ сделать это. Вы просто должны это сделать.
Допустим, вы можете эффективно захватить все действия и связанных с ними пользователей. Вы, вероятно, не можете сделать это эффективно, для чего-то столь же частого, как активность на веб-сайте, но гипотетически, скажем, вы могли бы, ради простоты.
То, что вы хотите, - это повторять ваши действия и собирать строки, которые вы хотите отобразить. Легкий путь, по моему скромному мнению, был бы просто методом поиска в вашей модели Activity
, который возвращает массивы последовательных действий пользователя.
Оставьте свои пороги для просмотра. (Не более 2 последовательных действий, всего не более 10 строк.)
Если в Ruby есть какой-то причудливый способ сбора последовательных элементов из массива, то я, вероятно, буду выглядеть глупо, но вот некоторый ( непроверенный ) код:
class Activity < ActiveRecord::Base
belongs_to :user
def self.each_consecutive_group(options={})
default_options = { :order => 'created_at DESC' }
current_group = nil
last_user_id = false
self.all(default_options.merge(options)).each do |activity|
# Look for consecutive activities from the same user.
# (This is never true on the first iteration.)
if last_user_id == activity.user_id
current_group << activity
else
# The nil case happens during first iteration.
yield current_group unless current_group.nil?
# Initialize state for the next group of activities.
current_group = [activity]
last_user_id = activity.user_id
end
end
# Do we still have something to yield?
yield current_group if current_group
end
# Just return the above as an array, rather than iterating.
def self.consecutive_groups(options={})
groups = []
self.each_consecutive_group(options) { |group| groups << group }
groups
end
end
# Usage:
Activity.each_grouped(:include => :user, :limit => 30) do |group|
# [...]
end
# Or if you want to pass something from the controller to the view:
@activity_groups = Activity.grouped(:include => :user, :limit => 30)
Чтобы затем уменьшить проблему с производительностью, я бы просто взял безопасный запас. Если вам нужно 10 строк, вы можете выбрать область из 20 видов деятельности для поиска, и в ней будет 10 скрытых записей. Больше, и вы можете увидеть менее 10 строк. Выбор 20 записей вряд ли много, и вы можете расширить это число.
Если вы твердо настроены на всегда с 10 строками, то вам, вероятно, придется передвинуть пороговый код в вышеприведенное любым способом. Затем вы можете использовать find_in_batches
вместо :limit
и продолжать цикл до тех пор, пока ваш порог не будет превышен.