Rails 3 – 渴望加载条件

好吧,我对这一点感到非常难过。 我正在尝试构建按类别组织的已发布网页菜单。

Category.rb:

belongs_to :parent, :class_name => "Category", :foreign_key => "parent_id" has_many :children, :class_name => "Category", :foreign_key => "parent_id" has_many :pages, :documents, :galleries 

Page.rb

 belongs_to :category 

Page模型也有:is_published,所以我也试图对它进行过滤。 我不愿意发布我的微弱查询尝试,但除了乞求更聪明的人之外,没有其他解决方案:

(自我是@current_website)

 self.categories.includes(:children, :pages).where('pages.is_published = 1') 

这主要返回我需要的内容,但不返回没有发布页面的父类别。 例如,如果我有:

 Parent Category - Published Page - Child Category -- Published Page 

失败的地方是我父母没有发布的页面,如下所示:

 Parent Category - Child Category -- Published Page - Child Category -- Published Page 

在此先感谢任何帮助。 我正在努力尽可能多地了解查询,但我在这方面已经反对了。

更新:实现KandadaBoggu的建议已经产生了更好的结果,这被添加到Category.rb

  has_many :published_pages, :class_name => "Page", :conditions => {:is_published => true} 

但是,使用以下内容时:

 self.categories.where(:parent_id => nil).includes({:children => :published_pages}, :published_pages) 

我得到了我需要的结果,但我也得到了空的父类别(没有published_pa​​ges,没有已发布页面的子类别。例如:

 - Parent Category -- Published Page - Parent Category -- NOTHING 

我的临时修复是附加查询:

 reject{|category| category.pages.empty? && category.children.empty?} 

再次感谢你的帮助。

添加一个名为published_pages的新关联(除了您当前的关联)

 class Category has_many :children, :class_name => "Category", :foreign_key => "parent_id" has_many :published_pages, :class_name => "Page", :conditions => { :is_published => true } end 

现在,您可以按如下方式获取所有类别:

 self.categories.includes(:children, :published_pages) 

如果您有兴趣了解为什么您的方法不起作用,请阅读Rails 文档 (在Eager loading of associations部分之后滚动10-15行)。 我在下面列出了相关代码:

例如

 Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all 

这将导致单个SQL查询具有以下行的连接:

 LEFT OUTER JOIN comments ON comments.post_id = posts.id and LEFT OUTER JOIN authors ON authors.id = posts.author_id. 

请注意,使用此类条件可能会产生意想不到的后果。 在上面的示例中,根本不返回带有概念批准注释的post,因为这些条件作为整体适用于SQL语句而不仅仅适用于关联。 您必须消除此回退的列引用的歧义,例如:order =>“author.name DESC”将起作用但是:order =>“name DESC”将不会。

要急切加载过滤的关联行,请使用与条件关联:

 class Post < ActiveRecord::Base has_many :approved_comments, :class_name => 'Comment', :conditions => ['approved = ?', true] end Post.find(:all, :include => :approved_comments)