Module: CollectiveIdea::Acts::NestedSet

Defined in:
lib/awesome_nested_set/helper.rb,
lib/awesome_nested_set/awesome_nested_set.rb

Overview

:nodoc:

Defined Under Namespace

Modules: Columns, Helper, Model

Instance Method Summary collapse

Instance Method Details

#acts_as_nested_set(options = {}) ⇒ Object

Configuration options are:

  • :parent_column - specifies the column name to use for keeping the position integer (default: parent_id)

  • :left_column - column name for left boundry data, default “lft”

  • :right_column - column name for right boundry data, default “rgt”

  • :depth_column - column name for the depth data, default “depth”

  • :scope - restricts what is to be considered a list. Given a symbol, it’ll attach “_id” (if it hasn’t been already) and use that as the foreign key restriction. You can also pass an array to scope by multiple attributes. Example: acts_as_nested_set :scope => [:notable_id, :notable_type]

  • :dependent - behavior for cascading destroy. If set to :destroy, all the child objects are destroyed alongside this object by calling their destroy method. If set to :delete_all (default), all the child objects are deleted without calling their destroy method.

  • :counter_cache adds a counter cache for the number of children. defaults to false. Example: acts_as_nested_set :counter_cache => :children_count

  • :order_column on which column to do sorting, by default it is the left_column_name Example: acts_as_nested_set :order_column => :position

See CollectiveIdea::Acts::NestedSet::Model::ClassMethods for a list of class methods and CollectiveIdea::Acts::NestedSet::Model for a list of instance methods added to acts_as_nested_set models



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/awesome_nested_set/awesome_nested_set.rb', line 44

def acts_as_nested_set(options = {})
  options = {
    :parent_column => 'parent_id',
    :left_column => 'lft',
    :right_column => 'rgt',
    :depth_column => 'depth',
    :dependent => :delete_all, # or :destroy
    :polymorphic => false,
    :counter_cache => false
  }.merge(options)

  if options[:scope].is_a?(Symbol) && options[:scope].to_s !~ /_id$/
    options[:scope] = "#{options[:scope]}_id".intern
  end

  class_attribute :acts_as_nested_set_options
  self.acts_as_nested_set_options = options

  include CollectiveIdea::Acts::NestedSet::Model
  include Columns
  extend Columns

  belongs_to :parent, :class_name => self.base_class.to_s,
                      :foreign_key => parent_column_name,
                      :counter_cache => options[:counter_cache],
                      :inverse_of => (:children unless options[:polymorphic]),
                      :polymorphic => options[:polymorphic]

  has_many_children_options = {
    :class_name => self.base_class.to_s,
    :foreign_key => parent_column_name,
    :order => order_column,
    :inverse_of => (:parent unless options[:polymorphic]),
  }

  # Add callbacks, if they were supplied.. otherwise, we don't want them.
  [:before_add, :after_add, :before_remove, :after_remove].each do |ar_callback|
    has_many_children_options.update(ar_callback => options[ar_callback]) if options[ar_callback]
  end

  has_many :children, has_many_children_options

  attr_accessor :skip_before_destroy

  before_create  :set_default_left_and_right
  before_save    :store_new_parent
  after_save     :move_to_new_parent, :set_depth!
  before_destroy :destroy_descendants

  # no assignment to structure fields
  [left_column_name, right_column_name, depth_column_name].each do |column|
    module_eval <<-"end_eval", __FILE__, __LINE__
      def #{column}=(x)
        raise ActiveRecord::ActiveRecordError, "Unauthorized assignment to #{column}: it's an internal field handled by acts_as_nested_set code, use move_to_* methods instead."
      end
    end_eval
  end

  define_model_callbacks :move
end