两个has_many关联到同一个模型

时间:2015-05-12 14:23:11

标签: ruby-on-rails ruby associations

我的博客模型有很多帖子,其中一些帖子是热门帖子。我的意图是拥有以下内容。

class Blog
  has_many :posts
  has_many :top_posts, class_name: 'Post'
end

class Post
  belongs_to :blog
end

如您所见,帖子和帖子帖子是相同的对象,但热门帖子的集合与帖子集合不同。有些帖子也是热门帖子,但有些帖子不是。

问题是,当我尝试blog.top_posts时,它会返回与blog.posts相同的集合,这些集合都是来自该博客的帖子。我希望blog.top_posts仅通过blog.top_post_ids << random_post返回我关联的帖子作为博客的热门帖子。提前谢谢!

3 个答案:

答案 0 :(得分:1)

我会假设,就像大卫在评论中问你一样,你有特别的帖子。

如果一个帖子可以成为一个top_post,例如,他有50个喜欢,或1000个视图,或者数据库中持久的wathever属性,使得帖子成为热门帖子。

如果您的数据库没有持久性标准,则无法使用活动记录获取top_post。 无论如何,你应该使用范围:

 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

你可以简单地得到它们:

    blog = Blog.first
    blog.posts.top_posts # => [top posts belonging to this blog]

这是基于假设的答案......

范围doc:http://guides.rubyonrails.org/active_record_querying.html#scopes 小号

答案 1 :(得分:1)

使用has_many的问题是它只是将Blog对象的ID附加到每个Post对象,因此当您致电blog.postsblog.top_posts时它执行查询Posts WITH id=Blog.id的SQL查询,因此,您获得两次相同的列表。

我建议你有一个has_many posts,然后对每个帖子返回的列表进行排序&#34; Top Post。&#34;或者,如果您想避免排序,我建议您这样做:

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

答案 2 :(得分:1)

范围怎么样? {{3}}

    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