Module: EvenBetterNestedSet::ClassMethods

Defined in:
lib/eb_nested_set.rb

Instance Method Summary collapse

Instance Method Details

#acts_as_nested_set(options = {}) ⇒ Object



304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/eb_nested_set.rb', line 304

def acts_as_nested_set(options = {})
  options = { :left => :left, :right => :right }.merge!(options)
  options[:scope] = "#{options[:scope]}_id" if options[:scope]
  
  include NestedSet
  
  self.nested_set_options = options
  
  class_eval <<-RUBY, __FILE__, __LINE__+1
    def #{options[:left]}=(left)
      raise EvenBetterNestedSet::IllegalAssignmentError, "#{options[:left]} is an internal attribute used by EvenBetterNestedSet, do not assign it directly as is may corrupt the data in your database"
    end

    def #{options[:right]}=(right)
      raise EvenBetterNestedSet::IllegalAssignmentError, "#{options[:right]} is an internal attribute used by EvenBetterNestedSet, do not assign it directly as is may corrupt the data in your database"
    end
  RUBY
  
  named_scope :roots, :conditions => { :parent_id => nil }, :order => "#{nested_set_column(:left)} asc"
  
  has_many :uncached_children, :class_name => self.name, :foreign_key => :parent_id, :order => "#{nested_set_column(:left)} asc"
  protected :uncached_children, :uncached_children=
  
  belongs_to :parent, :class_name => self.name, :foreign_key => :parent_id
  
  named_scope :descendants, lambda { |node|
    left, right = find_boundaries(node.id)
    { :conditions => ["#{nested_set_column(:left)} > ? and #{nested_set_column(:right)} < ?", left, right],
      :order => "#{nested_set_column(:left)} asc" }
  }
  
  before_create :append_node
  before_update :move_node
  before_destroy :reload
  after_destroy :remove_node
  validate_on_update :illegal_nesting
  validate :validate_parent_is_within_scope
  
  delegate :nested_set_column, :to => "self.class"
end