2010-07-04 3 views
1

У меня есть поток действий (активности), принадлежащих пользователям, и с созданным_атом. Я хотел бы представить поток из 10 последних мероприятий, с оговоркой, что я хочу объединить действия вместе. Я знаю, что могу использовать group_by, но я не хочу группировать все вместе пользователем, только те действия, которые появляются> 2 раза подряд.Как объединить элементы в потоке вместе, если они принадлежат одному и тому же пользователю

  • Том сказал, что что-то
  • Джо сделал что-то
  • Джо пнул что-то
  • Джо ударил что-то
  • Джо сказал что-то
  • Билл сделал что-то
  • Билл послал что-то

Если это было сгруппировано, это было бы так:

  • Том сказал, что что-то
  • Джо сделал что-то
  • Джо пнул что-то [Больше от Джо ...]
  • Билла сделал что-то
  • Билль отослал кое-что

Где больше ссылок будет открываться скрытый div.

+0

Не могли бы вы прояснить это для меня пожалуйста? Если он группирует то, что пользователь делал> 2 раза подряд, счет меньше 10. Затем вы хотите включить больше действий, пока не перечислите 10 действий для пользователя, или вы бы просто group_by только для последних 10 видов деятельности? –

+0

Правильно, Shripad, мы хотели бы получить больше активных действий, чтобы мы показывали предметы. – Newy

ответ

0

Я не думаю, что есть какой-либо особый способ сделать это. Вам просто нужно это сделать.

Предположим, вы могли бы эффективно захватить все действия и связанные с ними пользователи. Вероятно, вы не можете сделать это эффективно, для чего-то столь же частого, как активность на веб-сайте, но предположительно предположим, что вы могли бы, для простоты.

Вы хотите, чтобы повторять действия и собирать строки, которые вы хотите отобразить. Легкая дорога, по моему скромному мнению, просто была бы подобным методом на вашей модели Activity, которая возвращает массивы последовательных действий пользователя.

Оставьте свои пороговые значения для представления. (Не более двух последовательных действий, не более 10 строк.)

Если у Ruby есть некоторый причудливый способ сбора последовательных элементов из массива, то я, вероятно, буду выглядеть глупо, но вот некоторые (untested) код:

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, и продолжайте цикл до превышения порогового значения.

Смежные вопросы

 Смежные вопросы