"合并"多个模型.创建"最近活动"框

Arc*_*ath 11 activerecord ruby-on-rails

如何合并模型,以便我可以按顺序显示最后10个帖子,Feed条目和私人消息?

帖子存储在"Post"模型中,并在"created_at"上订购

Feed条目存储在"Planet"中,并在"published_at"上排序

私人消息存储在"消息"中,需要过滤:

:conditions => "receiver_id = #{current_user.id}"
Run Code Online (Sandbox Code Playgroud)

并在"created_at"上订购

Sim*_*tti 11

我会使用Proxy类.该类可以存储ActiveRecord对象引用和用于排序的字段.

class ActivityProxy
  attr_accessor :object, :date
  def initialize(object, date)
    self.object = object
    self.date = date
  end
end
Run Code Online (Sandbox Code Playgroud)

然后你加载你的对象.

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
Run Code Online (Sandbox Code Playgroud)

最后,您对对象进行排序

activity.sort_by(&:field)
# => here you have the sorted objects
# and you can iterate them with
activity.each do |proxy|
  proxy.object.id
  # ...
end
Run Code Online (Sandbox Code Playgroud)


gas*_*ard 11

你必须:

  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)]
Run Code Online (Sandbox Code Playgroud)

当然,根据您的模型,您必须更改使用哪种方法作为"标题"或"文本".

但是如果你碰巧需要很多这样的习语,你应该像在zena(rails CMS)中那样使用单表继承.