2014-05-14 74 views
2

我已經實現了這樣的事情:獲取集合所有的孩子在軌物體

class Move < ActiveRecord::Base 
    has_many :move_categories 
    has_many :categories, through: :move_categories 
end 

class Category < ActiveRecord::Base 
    has_many :move_categories 
    has_many :moves, through: :move_categories 
    belongs_to :parent, class_name: 'Category' 
    has_many :subcategories, class_name: 'Category', foreign_key: 'parent_id' 
end 

因此,對於給定的一類一,我需要找到讓我所有的移動的最佳方式,也是所有來自我的子類別的子類別和來自我的子類別的子類別的子類別等等。

有什麼想法?

編輯:

這裏的MoveCategory型號:

class MoveCategory < ActiveRecord::Base 
    belongs_to :move 
    belongs_to :category 

    validates_uniqueness_of :category_id, scope: :move_id 
end 
+0

在哪裏'move_categories'表? –

+0

你是否在使用PostGreSQL? – MrYoshiji

+0

所以你想找到屬於「Category」的所有'moves'?你的問題對我來說不是很清楚 –

回答

1

由於您使用PostreSQL,你應該採取WITH RECURSIVE CTE語法的優勢,做到這一點。看到http://hashrocket.com/blog/posts/recursive-sql-in-activerecord偉大的寫作。

如果要實現tree方法,唯一缺少的是移動檢索:

def Category < ActiveRecord::Base 
    def descendant_moves 
    tree_id_sql = self.class.tree_sql_for(self) 
    Move.joins(:move_categories).where("move_categories.category_id IN (#{tree_id_sql})") 
    end 
end 

爲了完整起見,這裏是從上面列出的頁面爲tree_sql_for方法的代碼:

def self.tree_sql_for(instance) 
    tree_sql = <<-SQL 
    WITH RECURSIVE search_tree(id, path) AS (
     SELECT id, ARRAY[id] 
     FROM #{table_name} 
     WHERE id = #{instance.id} 
     UNION ALL 
     SELECT #{table_name}.id, path || #{table_name}.id 
     FROM search_tree 
     JOIN #{table_name} ON #{table_name}.parent_id = search_tree.id 
     WHERE NOT #{table_name}.id = ANY(path) 
    ) 
    SELECT id FROM search_tree ORDER BY path 
    SQL 
end