“слияние” многоуровневых моделей. Создать “недавнее действие” поле

Как Вы объединяете модели так, чтобы у меня могли быть последние 10 Сообщений, Записи Канала и Личные сообщения, отображенные в порядке?

Сообщения сохранены в модели "Post" и заказаны на "created_at"

Записи канала сохранены в "Планете" и заказаны на "published_at"

Личные сообщения хранятся в "сообщении" и должны быть фильтрованы с:

:conditions => "receiver_id = #{current_user.id}"

и заказанный на "created_at"

11
задан Arcath 20 January 2010 в 08:18
поделиться

2 ответа

Вы должны:

  1. элементы запроса для каждой модели
  2. объединить их в общем формате
  3. Сортировка и ограничение

Вот какой-то код:

class Activity < Struct.new(:title, :text, :date); end

limit = 10
activities = []
activities += Post.all(:order => 'created_at DESC', :limit => limit).map do |post|
  Activity.new(post.title, post.summary, post.created_at)
end

activities += Planet.all(:order => 'published_at DESC', :limit => limit).map do |planet|
  Activity.new(planet.title, planet.message, planet.published_at)
end

activities += Message.all(:conditions => ['receiver_id = ?', current_user.id], :order => 'created_at DESC', :limit => limit).map do |message|
  Activity.new(message.title, message.text, message.created_at)
end

# descending sort by 'date' field
sorted_activities = activities.sort_by(&:date).reverse

# 10 most recent elements across all models
@activities = sorted_activities[0..(limit-1)]

, конечно, в зависимости от ваших моделей, вы придется изменить, какой метод используется как «название» или «текст».

Но если вы хотите, чтобы многие из таких идиом вы должны использовать одностое наследование стола, как мы делаем в Zena (рельсы CMS).

11
ответ дан 3 December 2019 в 04:52
поделиться

Я бы использовал прокси-класс. Класс может хранить ссылку на объект ActiveRecord и поле для сортировки.

class ActivityProxy
  attr_accessor :object, :date
  def initialize(object, date)
    self.object = object
    self.date = date
  end
end

Затем вы загружаете свои объекты.

activity = []
activity += Post.all(:limit => 10, :order => "created_at DESC").map { |post| ActivityProxy.new(post, post.created_at) }
# and so on with the other objects

Наконец-то вы сортируете объекты

activity.sort_by(&:field)
# => here you have the sorted objects
# and you can iterate them with
activity.each do |proxy|
  proxy.object.id
  # ...
end
11
ответ дан 3 December 2019 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: