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
I would like to have an instance method, such that I could do @newsroom.pos开发者_运维知识库ts to get a collection of blog_posts and quote_posts sorted by created_at.
def posts
@posts ||= #load and sort blog_posts, quote_posts, etc
end
What is the best and most efficient way to accomplish this? I have looked into using default_scope, something like:
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
But I would rather keep the sorting at the database level, if possible. Any suggestions on how to accomplish this? Thanks.
Try something like this:
#app/models/newsroom.rb
scope :ordered_posts, lambda {
includes(:blog_posts,:quote_posts) & BlogPost.order("created_at asc") & QuotePost.order("created_at asc")
}
ARel should be able to handle the ordering of included Quote and Blog Posts. You could clean that up slightly by having scopes in both the BlogPost and QuotePost model that order by created_at and then use those scopes in the Newsroom#ordered_posts method.
I ended up using a polymorphic post model. This seems to give me what I want with the insignificant downside of having an extra model/table. I used delegate to hand off specific attribute getter methods to the correct model.
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
精彩评论