Reputation: 401
I have a blog model that has many posts and some of these posts are top posts. My intention is to have something like the following.
class Blog
has_many :posts
has_many :top_posts, class_name: 'Post'
end
class Post
belongs_to :blog
end
As you can see, posts and top posts are the same objects, but the collection of top posts is different from the collection of posts. Some posts are top posts too, but others not.
The problem is when I try to do blog.top_posts
, it returns the same collection as blog.posts
, which are all posts from that blog. I want blog.top_posts
to return only the posts I have associated as the blog's top posts via blog.top_post_ids << random_post
. Thanks in advance!
Upvotes: 0
Views: 371
Reputation: 133
I will assume that , like David asked you in comment , you have particular post.
And a post could become a top_post if , by example , he has 50 likes , or 1000 views , or wathever attributes persistent in your database making a post become a top post .
If you don't have any criteria persistent on your database , you can't use active record to gets top_post. Anyway if you have , you should use a scope :
class Blog
has_many :posts
end
class Post
belongs_to :blog
scope :top_posts, -> { where(views > 1000 ) } #or any conditions base on your criterias
end
And you can get them simply :
blog = Blog.first
blog.posts.top_posts # => [top posts belonging to this blog]
it's an answer based on assumption ...
doc for scope : http://guides.rubyonrails.org/active_record_querying.html#scopes s
Upvotes: 1
Reputation: 66
How about a scope? http://guides.rubyonrails.org/active_record_querying.html#scopes
class Blog has_many :posts end class Post belongs_to :blog scope :top, -> { where top_post: true } end # this gets all the top posts blog.posts.top
Upvotes: 1
Reputation: 1480
The problem with using the has_many
is it simply attaches the ID of your Blog
object to each Post
object so when you call blog.posts
or blog.top_posts
it executes a SQL query looking for Posts WITH id=Blog.id
thus, you get the same list twice.
I would suggest you have a single has_many posts
and then sort the list that is returned by whatever makes each post the "Top Post." Or, if you'd like to avoid sorting I'd suggest something like this:
class Blog
has_many :posts
def initialize
@top_posts = []
end
def add_top_post(post)
if self.posts.include?(post)
@top_posts << post
end
end
end
class Post
belongs_to :blog
end
Upvotes: 1