2010-10-22 105 views
1

我有樹狀結構大致是這樣的:查找無子女的節點在樹狀結構使用Rails

class Node < ActiveRecord::Base 
    belongs_to :parent, :class_name => self.to_s, :foreign_key => 'parent_id' 
    has_many :children, :class_name => self.to_s, :foreign_key => 'parent_id', :dependent => :destroy 
    ... 
end 

我可以載入沒有父母與此範圍內的所有節點:

named_scope :not_child, :conditions => 'parent_id IS NULL' 

但我還需要找到沒有孩子,但可以有一個父母,我很難與它的節點。我想我必須包括children_events但後來我迷路了,我不能使用:

named_scope, :faulty_not_parent, :include => :children, :conditions => "node.parent_id IS NULL" 

回答

3

明白了:

named_scope :not_parent, :conditions => "id NOT IN (SELECT DISTINCT parent_id FROM nodes WHERE parent_id IS NOT NULL)" 
+0

這可行,但我編輯了你的答案來搜索「節點」表,以便它與你的問題中的例子相匹配。這將避免與將來閱讀此答案的人混淆。 – 2010-10-22 20:04:19

+0

謝謝對不起! – Macario 2010-10-22 22:19:21

+0

我的作用域本身工作,但使用其他作用域時,我有一個不明確的列名稱問題,必須對列名稱更具體一點:named_scope:not_parent,:conditions =>「nodes.id NOT IN(SELECT DISTINCT nodes。 parent_id FROM nodes WHERE nodes.parent_id IS NOT NULL)「 – Macario 2010-10-22 22:28:07

0

我不是一個SQL大師,所以我不能找出一個在純SQL中執行此操作的好方法。當然,這意味着我無法通過named_scopes找到一種方法。但你可以找到父母,並減去所有節點,就像這樣:

def childless 
@childless ||= self.all - self.all(:joins => :children) 
end 

這不是優雅,我想,因爲它需要加載大量的內存。但它只需要2個select語句,這是很好的。我會很樂意看到其他答案。