2010-11-16 80 views
10

好的,我完全沉迷於這一個。我正在嘗試構建按類別組織的已發佈網頁菜單。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 

頁面模型也有: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 

在此先感謝。我試圖儘可能多地學習關於查詢的知識,但是我對此很反感。

UPDATE:實現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?} 

再次感謝您的幫助。

回答

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 

現在,你可以得到所有的類別如下:

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

如果您有興趣瞭解爲什麼你的方法沒有工作,閱讀Rails documentation(在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. 

注意,使用類似的條件這可能會產生意想不到的後果。 在上面的示例中,由於條件適用於整個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) 
+0

感謝最優秀的寫了,鏈路和解釋,KandadaBoggu!這確實使我走上了正確的道路,對於self.categories.includes(:children =>:published_pa​​ges,:published_pa​​ges),我仍然存在一個問題,那就是爲父母提供沒有頁面或子類別的父頁。再次感謝! – TMB 2010-11-17 16:16:28

+0

更新您的問題並指定您的要求w.r.t存在/不存在頁面。 – 2010-11-17 18:30:18

+0

非常有幫助謝謝 - 拉着我的頭髮 – jpwynn 2012-06-10 17:19:00