«слияние» нескольких моделей.Чтобы создать поле «Недавние действия» - PullRequest
11 голосов
/ 20 января 2010

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

Сообщения хранятся в модели "Post" и упорядочиваются по "made_at"

Записи в фиде хранятся в «Планете» и упорядочиваются в «ключе публикации»

Личные сообщения хранятся в «Сообщение» и должны быть отфильтрованы с помощью:

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

и заказано на "create_at"

Ответы [ 3 ]

11 голосов
/ 20 января 2010

Вы должны:

  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 голосов
/ 20 января 2010

Я бы использовал прокси-класс.Класс может хранить ссылку на объект 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
1 голос
/ 07 января 2016

Другой метод создания каналов - это создание VIEW, который объединяет два, а затем позволяет представлению иметь свою собственную модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...