附加到活动记录关系对象

时间:2015-01-02 13:28:06

标签: ruby-on-rails ruby ruby-on-rails-3 rails-activerecord

我有一个Post模型。具有查找已启用帖子的范围。帖子可以属于某个类别。我也有一个类别模型,排名类别。类别有很多帖子。我想显示属于不同类别的第一个不同的20个帖子(前20个类别),然后按发布时间的降序显示帖子的其余部分。

这就是我所拥有的

Post model

class Post < ActiveRecord::Base
belongs_to :categories
scope :by_category, ->(category) { joins(categories).where(categories: { id: category.id }) }
scope :enabled, where(disabled: false)
scope :recent, order('published_at DESC')

Category model

class Category < ActiveRecord::Base
has_many :feeds
scope :most_popular, order('rank ASC')

Home Controller

def index
  Category.most_popular.limit(20).each do |cat|
    @posts= Post.enabled.recent.by_category(cat).page(1).per(30)
  end

在视图文件中我正在使用@posts呈现我收到的帖子的属性。但很明显,它只返回循环中找到的最后一个类别的帖子。基本上它不会附加。我尝试使用&lt;&lt;附加..如 -

@posts <<  Post.enabled.recent.by_category(cat).page(1).per(30)

但它没有给出任何方法&lt;&lt;为零:零级

我尝试将@posts作为一个数组,然后它不会占用kaminari的页面和每个页面。

我尝试使用new将@posts作为ActiveRecord :: Relation对象,它给出了参数错误。

我尝试将@posts作为Post的对象,但后来它说未定义的方法&lt;&lt;对于Post,从那时起,&lt;&lt;不是我的模型类的方法。我也跟着一些SO posts,但它似乎不符合我的步骤。

基本上,我对实现这一点的见解是将记录追加到模型对象中,然后显示对象。我甚至怀疑,如果我的方法足够好的话。可能有更有效的方法来做到这一点,我可能在RoR中错过了。

2 个答案:

答案 0 :(得分:2)

你可以这样做:

def index
  posts_ids = []
  Category.most_popular.limit(20).each do |cat|
    post_ids << Post.enabled.recent.by_category(cat).map(&:id)
  end
  @posts = Post.find( post_ids ).page(1).per(30)
end

答案 1 :(得分:1)

让我定义您的问题,以确保我正确理解它。在您的视图中,您需要先了解每个类别的最新帖子。然后你想要他们最近订购的所有帖子。

我会在控制器中创建两个实例变量,以便稍后在视图中使用。

def index
  enabled_posts = Post.enabled.recent

  @category_posts = enabled_posts.joins(:categories).group("categories.id")

  exclude_post_ids = @category_posts.pluck("posts.id")

  @posts = enabled_posts.where("id NOT IN (?)", exclude_post_ids)
end

如果您使用两个不同的部分来显示@category_posts和剩余的帖子,则上述内容应该会很方便。但是,如果您使用单个部分并且希望在单个变量中订购所有帖子,那么只需将控制器代码更改为以下内容:

def index
  enabled_posts = Post.enabled.recent

  category_posts = enabled_posts.joins(:categories).group("categories.id")

  exclude_post_ids = @category_posts.pluck("posts.id")

  remaining_posts = enabled_posts.where("id NOT IN (?)", exclude_post_ids)

  @posts = category_posts + remaining_posts
end