我已经实现了这样的事情:
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 :(得分: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