Мне удалось сделать это по-другому, но это может не сработать для вашей ситуации. Я рефинансировал существующий код и не хотел, чтобы какая-либо серьезная миграция базы данных.
Мне нужны отдельные классы листьев и узлов. Оба наследуются от древовидного класса.
Я добавил две функции в методы класса в vendor/plugins/acts_as_tree/lib/active_record/acts/tree.rb
:
# Configuration options are:
#
# * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
# * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
# * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
# * <tt>leaf_class_name</tt> - leaf class subtype of base tree class
# * <tt>node_class_name</tt> - node class subtype of base tree class
def acts_as_tree_node(options = {})
configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil, :node_class_name => 'Node', :leaf_class_name => 'Leaf' }
configuration.update(options) if options.is_a?(Hash)
belongs_to :parent, :class_name => configuration[:node_class_name], :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
#has_many :children, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy
class_eval <<-EOV
has_many :child_nodes, :class_name => '#{configuration[:node_class_name]}', :foreign_key => "#{configuration[:foreign_key]}", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}, :dependent => :destroy
has_many :child_leaves, :class_name => '#{configuration[:leaf_class_name]}', :foreign_key => "#{configuration[:foreign_key]}", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}, :dependent => :destroy
include ActiveRecord::Acts::Tree::InstanceMethods
def self.roots
find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
end
def self.root
find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
end
EOV
end
# Configuration options are:
#
# * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+)
# * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet.
# * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+).
# * <tt>node_class_name</tt> - the class name of the node (subclass of the tree base)
def acts_as_tree_leaf(options = {})
configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil, :node_class_name => 'Node' }
configuration.update(options) if options.is_a?(Hash)
belongs_to :parent, :class_name => configuration[:node_class_name], :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache]
class_eval <<-EOV
include ActiveRecord::Acts::Tree::InstanceMethods
def self.roots
find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
end
def self.root
find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}})
end
EOV
end
Затем в InstanceMethods, я добавил одну функцию:
# Returns list of children, whether nodes or leaves.
#
# NOTE: Will not return both, because that would take two queries and
# order will not be preserved.
def children
child_leaves.count == 0 ? child_nodes : child_leaves
end
Это немного рубить, но это работает для меня поскольку каждый узел имеет один тип подмножеств. Вы можете играть с функцией children
, чтобы получить другое поведение, например, следующим образом:
def children
child_nodes | child_leaves
end
Но он по-прежнему принимает дополнительный запрос, и вы потеряете ваш заказ и областей и прочее.
Наконец, в моем классе Node, у меня есть
acts_as_tree_node :node_class_name => 'NodeMatrix', :leaf_class_name => 'LeafMatrix'
и в моем классе листьев, следующие:
acts_as_tree_leaf :node_class_name => 'NodeMatrix'
Оба эти наследуют от TreeMatrix, который является чисто виртуальным (нет ничего фактически созданный как TreeMatrix, это просто базовый класс).
Опять же, это очень специфично для конкретного приложения. Но это дает вам представление о том, как вы можете изменять act_as_tree.
Отлично! Это отлично поработало для меня. Спасибо ... –
это означает, что сообщение и группа будут иметь has_one: container: as =>: сдерживаемый? – corroded