Changeset 7

Show
Ignore:
Timestamp:
08/15/06 00:58:32 (2 years ago)
Author:
jcm
Message:

helper added

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Rakefile.rb

    r2 r7  
    66task :default => :test 
    77 
    8 desc 'Test the plugin.' 
     8desc 'Test the better_nested_set plugin.' 
    99Rake::TestTask.new(:test) do |t| 
    1010  t.libs << 'lib' 
    11   t.test_files = ['test/preload_active_support.rb'] + FileList['test/t_*.rb'] + FileList['activesupport_mb/test/multibyte/*.rb'] 
     11  t.test_files = ['test/preload_active_support.rb'] + FileList['test/t_*.rb'] + FileList['lib/*.rb'] 
    1212  t.verbose = true 
    1313end 
  • trunk/init.rb

    r5 r7  
    44# 
    55require 'better_nested_set' 
     6require 'better_nested_set_helper' 
    67 
    78ActiveRecord::Base.class_eval do 
    89  include SymetrieCom::Acts::NestedSet 
    910end 
    10 # later... ActionView::Base.send :include, BetterNestedSetHelper 
     11ActionView::Base.send :include, SymetrieCom::Acts::BetterNestedSetHelper 
  • trunk/lib/better_nested_set.rb

    r6 r7  
    6565        # * +left_column+ - column name for left boundry data, default "lft" 
    6666        # * +right_column+ - column name for right boundry data, default "rgt" 
     67        # * +text_column+ - column name for the title field (optional). Used as default in the  
     68        #   {your-class}_options_for_select helper method. If empty, will use the first string field  
     69        #   of your model class. 
    6770        # * +scope+ - restricts what is to be considered a list. Given a symbol, it'll attach "_id"  
    6871        #   (if that hasn't been already) and use that as the foreign key restriction. It's also possible  
     
    8386               :left_column    => (options[:left_column]   || 'lft'), 
    8487               :right_column   => (options[:right_column]  || 'rgt'), 
    85                :scope          => (options[:scope] || '1 = 1') } ) 
     88               :scope          => (options[:scope] || '1 = 1'), 
     89               :text_column    => (options[:text_column] || columns.collect{|c| (c.type == :string) ? c.name : nil }.compact.first) 
     90              } ) 
    8691                
    8792          class_inheritable_reader :acts_as_nested_set_options 
     
    97102            end 
    98103            def #{acts_as_nested_set_options[:right_column]}=(x) 
    99              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." 
     104              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." 
    100105            end 
    101106            def #{acts_as_nested_set_options[:parent_column]}=(x) 
    102              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." 
     107              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." 
    103108            end 
    104109          end_eval 
     
    106111          include SymetrieCom::Acts::NestedSet::InstanceMethods 
    107112          extend SymetrieCom::Acts::NestedSet::ClassMethods 
     113           
     114          # adds the helper for the class 
     115#          ActionView::Base.send(:define_method, "#{Inflector.underscore(self.class)}_options_for_select") { special=nil 
     116#              "#{acts_as_nested_set_options[:text_column]} || "#{self.class} id #{id}" 
     117#            } 
     118           
    108119        end         
    109       end 
    110        
    111       module ClassMethods 
    112             # Returns the single root 
    113           def root 
    114               self.find(:first, :conditions => "(#{acts_as_nested_set_options[:scope]} AND #{acts_as_nested_set_options[:parent_column]} IS NULL)") 
    115           end                     
    116             # Returns roots when multiple roots (or virtual root, which is the same) 
    117           def roots 
    118               self.find(:all, :conditions => "(#{acts_as_nested_set_options[:scope]} AND #{acts_as_nested_set_options[:parent_column]} IS NULL)", :order => "#{acts_as_nested_set_options[:left_column]}") 
    119           end                               
     120 
     121        # Returns the single root 
     122        def root 
     123          self.find(:first, :conditions => "(#{acts_as_nested_set_options[:scope]} AND #{acts_as_nested_set_options[:parent_column]} IS NULL)") 
     124        end 
     125         
     126        # Returns roots when multiple roots (or virtual root, which is the same) 
     127        def roots 
     128          self.find(:all, :conditions => "(#{acts_as_nested_set_options[:scope]} AND #{acts_as_nested_set_options[:parent_column]} IS NULL)", :order => "#{acts_as_nested_set_options[:left_column]}") 
     129        end                               
    120130      end 
    121131       
     
    252262                                                                
    253263        # Returns a set of itself and all of its nested children 
    254         def full_set 
     264        # Pass :exclude => item, or id, or [items or id] to exclude some parts of the tree 
     265        def full_set(special=nil) 
    255266          return [self] if new_record? or self[acts_as_nested_set_options[:right_column]]-self[acts_as_nested_set_options[:left_column]] == 1 
    256           self.class.find(:all, :conditions => "#{acts_as_nested_set_options[:scope]} AND (#{acts_as_nested_set_options[:left_column]} BETWEEN #{self[acts_as_nested_set_options[:left_column]]} and #{self[acts_as_nested_set_options[:right_column]]})", :order => acts_as_nested_set_options[:left_column]) 
     267#          self.class.find(:all, :conditions => "#{acts_as_nested_set_options[:scope]} AND (#{acts_as_nested_set_options[:left_column]} BETWEEN #{self[acts_as_nested_set_options[:left_column]]} and #{self[acts_as_nested_set_options[:right_column]]})", :order => acts_as_nested_set_options[:left_column]) 
     268          [self] + all_children(special) 
    257269        end 
    258270                   
    259271        # Returns a set of all of its children and nested children 
    260         def all_children 
     272        # Pass :exclude => item, or id, or [items or id] to exclude some parts of the tree 
     273        def all_children(special=nil) 
     274          if special && special[:exclude] 
     275            transaction do 
     276              # exclude some items and all their children 
     277              special[:exclude] = [special[:exclude]] if !special[:exclude].is_a?(Array) 
     278              # get objects for ids 
     279              special[:exclude].collect! {|s| s.is_a?(self.class) ? s : self.class.find(s)} 
     280              # get all subtrees and flatten the list 
     281              exclude_list = special[:exclude].map{|e| e.full_set.map{|ee| ee.id}}.flatten.uniq.join(',') 
     282              if exclude_list.blank? 
     283                self.class.find(:all, :conditions => "#{acts_as_nested_set_options[:scope]} AND (#{acts_as_nested_set_options[:left_column]} > #{self[acts_as_nested_set_options[:left_column]]}) and (#{acts_as_nested_set_options[:right_column]} < #{self[acts_as_nested_set_options[:right_column]]})", :order => acts_as_nested_set_options[:left_column]) 
     284              else 
     285                self.class.find(:all, :conditions => "#{acts_as_nested_set_options[:scope]} AND id NOT IN (#{exclude_list}) AND (#{acts_as_nested_set_options[:left_column]} > #{self[acts_as_nested_set_options[:left_column]]}) and (#{acts_as_nested_set_options[:right_column]} < #{self[acts_as_nested_set_options[:right_column]]})", :order => acts_as_nested_set_options[:left_column]) 
     286              end 
     287            end 
     288          else 
    261289            self.class.find(:all, :conditions => "#{acts_as_nested_set_options[:scope]} AND (#{acts_as_nested_set_options[:left_column]} > #{self[acts_as_nested_set_options[:left_column]]}) and (#{acts_as_nested_set_options[:right_column]} < #{self[acts_as_nested_set_options[:right_column]]})", :order => acts_as_nested_set_options[:left_column]) 
     290          end 
    262291        end 
    263292 
     
    383412         
    384413      end 
     414       
    385415    end 
    386416  end