Rails 3 - 渴望加载条件

TMB*_*TMB 10 mysql ruby-on-rails rails-activerecord

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

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
Run Code Online (Sandbox Code Playgroud)

Page.rb

belongs_to :category
Run Code Online (Sandbox Code Playgroud)

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

(自我是@current_website)

self.categories.includes(:children, :pages).where('pages.is_published = 1')
Run Code Online (Sandbox Code Playgroud)

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

Parent Category
- Published Page
- Child Category
-- Published Page
Run Code Online (Sandbox Code Playgroud)

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

Parent Category
- Child Category
-- Published Page
- Child Category
-- Published Page
Run Code Online (Sandbox Code Playgroud)

在此先感谢任何帮助.我正在尽可能多地学习有关查询的内容,但我在这方面已经反对了.

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

  has_many :published_pages, :class_name => "Page",
                             :conditions => {:is_published => true}
Run Code Online (Sandbox Code Playgroud)

但是,使用以下内容时:

self.categories.where(:parent_id => nil).includes({:children => :published_pages},
                                                   :published_pages)
Run Code Online (Sandbox Code Playgroud)

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

- Parent Category
-- Published Page
- Parent Category
-- NOTHING
Run Code Online (Sandbox Code Playgroud)

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

reject{|category| category.pages.empty? && category.children.empty?}
Run Code Online (Sandbox Code Playgroud)

再次感谢你的帮助.

Har*_*tty 14

添加一个名为的新关联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
Run Code Online (Sandbox Code Playgroud)

现在您可以获得以下所有类别:

self.categories.includes(:children, :published_pages)
Run Code Online (Sandbox Code Playgroud)

如果你有兴趣,为什么你的方法没有工作,阅读Rails的文档(滚动后10-15线Eager loading of associations部分).我在下面列出了相关代码:

例如

Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all
Run Code Online (Sandbox Code Playgroud)

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

LEFT OUTER JOIN comments ON comments.post_id = posts.id and 
LEFT OUTER JOIN authors  ON authors.id = posts.author_id. 
Run Code Online (Sandbox Code Playgroud)

请注意,使用此类条件可能会产生意想不到的后果.在与概念批准评论上面的例子中的职位不返回可言,因为条件适用于SQL语句作为一个整体,而不仅仅是联想.你必须消除歧义的列引用此回退的情况发生,例如:为了=>"author.name DESC"会工作,但:为了=>"的名字DESC"不会.

到关联的急切装载过滤的行,使用带有条件的关联:

class Post < ActiveRecord::Base
  has_many :approved_comments, :class_name => 'Comment', 
             :conditions => ['approved = ?', true]
end

Post.find(:all, :include => :approved_comments)
Run Code Online (Sandbox Code Playgroud)