附加到活动记录关系对象

append to an active record relations object

我有一个 Post 模型。具有找到启用的 posts.A post 的范围可以属于一个类别。我还有一个类别模型,类别排名。类别有很多 post。我想首先显示属于不同类别(前 20 个类别)的 20 个不同 post,然后按 published_time 的降序显示其余 post。

这就是我的

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 接收到的post 的属性。但很明显,它 returns 只是在循环中找到的最后一个类别的 post。基本上它不会追加。我尝试使用 << 附加..如 -

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

但是它没有给出方法 << for nil:nil class

我尝试将@posts 制作成一个数组,但它并没有让 page 和 per of kaminari 发挥作用。

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

我尝试将 @posts 作为 Post 的对象,但随后它说未定义方法 << for Post,因为当然,<< 不是我模型的方法class。我也关注了一些 SO posts 但它似乎不适合我的步骤。

基本上,我对实现这一目标的见解是将记录附加到模型对象中,然后显示该对象。我什至怀疑我的方法是否足够好。可能有更有效的方法来做到这一点,我可能在 RoR 中遗漏了这一点。

你可以这样做:

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

让我来定义您的问题,以确保我理解正确。在您看来,您首先想要每个类别的最新 post。然后您希望所有 post 都按最近时间排序。

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

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 和其余的 post,以上内容应该很方便。但是,如果您使用的是单个部分,并且希望所有 post 在单个变量中排序,则只需将您的控制器代码更改为以下内容:

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