Ruby on rails 是否排除RubyonRails中的空模型?

Ruby on rails 是否排除RubyonRails中的空模型?,ruby-on-rails,Ruby On Rails,我有一个webApp,上面有帖子和分类。每个类别可以有多个帖子,一个帖子只属于一个类别 在索引视图中,我想显示按类别排序的帖子,因此我的视图是: <% @categories.each do |category| %> #shows category name <% @posts.each do |post| %> <% if post.category_id == category.id.to_s %> #shows summar

我有一个webApp,上面有帖子和分类。每个类别可以有多个帖子,一个帖子只属于一个类别

在索引视图中,我想显示按类别排序的帖子,因此我的视图是:

<% @categories.each do |category| %>
  #shows category name
  <% @posts.each do |post| %>
    <% if post.category_id == category.id.to_s %>
      #shows summary of post fields in a row; such as title, date, etc
    <% end %>
  <% end %>
<% end %>
另一个困扰我的问题是,我的视图每次都会循环浏览所有类别和帖子以显示行,如果帖子数量很大,这可能会减慢应用程序的速度。你知道如何更有效地做到这一点吗

更新:

目前实施的解决方案,包括过滤超过3天的帖子(更多信息请参见评论)。在控制器中:

 def index
@categories = Category.includes(:posts).select{|c| c.posts.where(['created_at > ?', 3.days.ago]).count > 0} 
end
这只加载包含最近3天创建的帖子的类别。请注意,如果类别中的某些帖子超过3天,则仍会加载超过3天的帖子

在视图中,我过滤那些我不想显示的超过3天的帖子

  <% @categories.each do |category| %>
  # do  category stuff
     <% category.posts.where(['created_at > ?', 3.days.ago]).each do |post| %>
     # do post stuff
     <% end %>
  <% end %>

#做分类工作
#发邮件

我很确定这是一种更好的方法,但至少这样db只被调用一次。

假设您在模型上正确地设置了关联,您不需要单独调用post和categories,因为您可以在categories上包含post,所以您不必要地创建了一个额外的db调用。类似地,您也可以将没有帖子的类别排除在外

  def index
    @categories = Category.includes(:posts).select{|c| c.posts.count > 0}
  end
因此,我们在这里所做的是,包括帖子,这样我们就不必在迭代帖子时进行额外的db调用。其次,我们使用select和一个块来提供一个自定义条件,通过迭代初始范围,只匹配类别和帖子。这里需要注意的是,select将返回一个对象数组,而不是活动记录关联(尽管使用“.all”仍会执行此操作)

然后,在页面上迭代此数组,如下所示:

<% @categories.each do |category| %>
      # do  category stuff
   <% category.posts.each do |post| %>
      # do post stuff
   <% end %>
<% end %>

#做分类工作
#发邮件

显示您的
post.rb
category.rb
,如果您已经设置了这两个模型之间的关联,
@posts=post。所有的
都是不必要的,因为您将通过
category.posts
访问
帖子。虽然没有包括在我的原始问题中,但我也会过滤以仅显示在过去3天内创建的帖子,因此我的控制器实际上是
@posts=post.where(['created_>?',3.days.ago])。我想这也可以在您的解决方案中完成;你会把这个条件包括在哪里?在控制器中还是在视图中?我不知道如何将其直接包含在控制器中。我假设在视图中,这将起作用
category.posts.where(['created_at>?',3.days.ago])。执行此操作的最佳位置是在控制器中。类别。包括(:posts)。其中(['created_at>?',3.days.ago])。选择{c | c.posts.count>0}这似乎可以过滤超过3天的类别;但目的是过滤超过3天的帖子。我可以在视图中这样做,但我想在控制器中这样做,以避免加载所有帖子,只显示在过去3天中创建的帖子。
<% @categories.each do |category| %>
      # do  category stuff
   <% category.posts.each do |post| %>
      # do post stuff
   <% end %>
<% end %>