Rails:我如何通过实例方法来加载关联加载关联?

时间:2011-04-16 13:48:06

标签: ruby-on-rails ruby ruby-on-rails-3 associations eager-loading

class Newsroom < ActiveRecord::Base
  has_many :blog_posts
  has_many :quote_posts
end

class BlogPost < ActiveRecord::Base
  belongs_to :newsroom
end 

class QuotePost < ActiveRecord::Base
  belongs_to :newsroom
end

我想有一个实例方法,这样我就可以使用@ newsroom.posts来获取按created_at排序的blog_posts和quote_posts的集合。

def posts
   @posts ||= #load and sort blog_posts, quote_posts, etc
end

实现这一目标的最佳和最有效的方法是什么?我已经研究过使用default_scope,例如:

default_scope :include => [:blog_posts, :quote_posts]

def posts
  @posts ||= [blog_posts + quote_posts].flatten.sort{|x,y| x.created_at <=> y.created_at}
end

但是如果可能的话,我宁愿在数据库级别保持排序。有关如何完成此任务的任何建议?感谢。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情:

#app/models/newsroom.rb

scope :ordered_posts, lambda {
  includes(:blog_posts,:quote_posts) & BlogPost.order("created_at asc") & QuotePost.order("created_at asc")
}

ARel应该能够处理包含的Quote和博客帖子的排序。你可以通过在created_at中排序的BlogPost和QuotePost模型中使用范围来稍微清理一下,然后在Newsroom#ordered_posts方法中使用这些范围。

答案 1 :(得分:0)

我最终使用了多态的帖子模型。这似乎给了我想要的东西,有一个额外的模型/表的微不足道的缺点。我使用委托将特定的属性getter方法移交给正确的模型。

class Newsroom < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belong_to :blog_post, :polymorphic => true

  delegate :title, :author, :etc, :to => :postable
end

class BlogPost < ActiveRecord::Base
  has_one :post, :as => :postable
end