我有一个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中错过了。
答案 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