module SymetrieCom::Acts::NestedSet::ClassMethods
This module provides an enhanced acts_as_nested_set
mixin for ActiveRecord. Please see the README for background information, examples, and tips on usage.
Public Instance Methods
Configuration options are:
-
dependent
- behaviour for cascading destroy operations (default: :delete_all) -
parent_column
- Column name for the parent/child foreign key (default:parent_id
). -
left_column
- Column name for the left index (default:lft
). -
right_column
- Column name for the right index (default:rgt
). NOTE: Don’t useleft
andright
, since these are reserved database words. -
scope
- Restricts what is to be considered a tree. Given a symbol, it’ll attach “_id” (if it isn’t there already) and use that as the foreign key restriction. It’s also possible to give it an entire string that is interpolated if you need a tighter scope than just a foreign key. Example:acts_as_nested_set :scope => 'tree_id = #{tree_id} AND completed = 0'
-
text_column
- Column name for the title field (optional). Used as default in the {your-class}_options_for_select helper method. If empty, will use the first string field of your model class.
# File lib/symetrie_com/acts_as_better_nested_set.rb, line 24 def acts_as_nested_set(options = {}) extend(SingletonMethods) unless respond_to?(:find_in_nestedset) options[:scope] = "#{options[:scope]}_id".intern if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/ write_inheritable_attribute(:acts_as_nested_set_options, { :parent_column => (options[:parent_column] || 'parent_id'), :left_column => (options[:left_column] || 'lft'), :right_column => (options[:right_column] || 'rgt'), :scope => (options[:scope] || '1 = 1'), :text_column => (options[:text_column] || columns.collect{|c| (c.type == :string) ? c.name : nil }.compact.first), :class => self, # for single-table inheritance :dependent => (options[:dependent] || :delete_all) # accepts :delete_all and :destroy } ) class_inheritable_reader :acts_as_nested_set_options base_set_class.class_inheritable_accessor :acts_as_nested_set_scope_enabled base_set_class.acts_as_nested_set_scope_enabled = true if acts_as_nested_set_options[:scope].is_a?(Symbol) scope_condition_method = %( def scope_condition if #{acts_as_nested_set_options[:scope].to_s}.nil? self.class.use_scope_condition? ? "#{table_name}.#{acts_as_nested_set_options[:scope].to_s} IS NULL" : "(1 = 1)" else self.class.use_scope_condition? ? "#{table_name}.#{acts_as_nested_set_options[:scope].to_s} = \#{#{acts_as_nested_set_options[:scope].to_s}}" : "(1 = 1)" end end ) else scope_condition_method = "def scope_condition(); self.class.use_scope_condition? ? \"#{acts_as_nested_set_options[:scope]}\" : \"(1 = 1)\"; end" end # skip recursive destroy calls attr_accessor :skip_before_destroy # no bulk assignment attr_protected acts_as_nested_set_options[:left_column].intern, acts_as_nested_set_options[:right_column].intern, acts_as_nested_set_options[:parent_column].intern # no assignment to structure fields class_eval <<-EOV before_create :set_left_right before_destroy :destroy_descendants include SymetrieCom::Acts::NestedSet::InstanceMethods def #{acts_as_nested_set_options[:left_column]}=(x) raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{acts_as_nested_set_options[:left_column]}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead." end def #{acts_as_nested_set_options[:right_column]}=(x) raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{acts_as_nested_set_options[:right_column]}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead." end def #{acts_as_nested_set_options[:parent_column]}=(x) raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{acts_as_nested_set_options[:parent_column]}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead." end #{scope_condition_method} EOV end