Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 3493

Show
Ignore:
Timestamp:
01/29/06 00:37:39 (3 years ago)
Author:
david
Message:

Added reusable reloading support through the inclusion of the Relodable module that all subclasses of ActiveRecord::Base, ActiveRecord::Observer, ActiveController::Base, and ActionMailer::Base automatically gets [DHH]. Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar]. Refactored extensions to module, class, and object in active support [DHH]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionmailer/lib/action_mailer/base.rb

    r3040 r3493  
    121121  class Base 
    122122    include AdvAttrAccessor, PartContainer 
     123 
     124    # Action Mailer subclasses should be reloaded by the dispatcher in Rails 
     125    # when Dependencies.mechanism = :load. 
     126    def self.inherited(child) #:nodoc: 
     127      child.send :include, Reloadable 
     128      super 
     129    end 
    123130 
    124131    private_class_method :new #:nodoc: 
  • trunk/actionpack/lib/action_controller/base.rb

    r3476 r3493  
    225225  class Base 
    226226    DEFAULT_RENDER_STATUS_CODE = "200 OK" 
     227 
     228    # Action Controller subclasses should be reloaded by the dispatcher in Rails 
     229    # when Dependencies.mechanism = :load. 
     230    def self.inherited(child) #:nodoc: 
     231      child.send :include, Reloadable 
     232      super 
     233    end 
    227234   
    228235    # Determines whether the view has access to controller internals @request, @response, @session, and @template. 
  • trunk/actionpack/lib/action_controller/layout.rb

    r3472 r3493  
    11module ActionController #:nodoc: 
    22  module Layout #:nodoc: 
    3     def self.append_features(base) 
    4       super 
     3    def self.included(base) 
     4      base.extend(ClassMethods) 
    55      base.class_eval do 
    66        alias_method :render_with_no_layout, :render 
     
    99        class << self 
    1010          alias_method :inherited_without_layout, :inherited 
    11         end 
    12       end 
    13       base.extend(ClassMethods) 
     11          alias_method :inherited, :inherited_with_layout 
     12        end 
     13      end 
    1414    end 
    1515 
     
    173173 
    174174      private 
    175         def inherited(child) 
     175        def inherited_with_layout(child) 
    176176          inherited_without_layout(child) 
     177          child.send :include, Reloadable 
    177178          layout_match = child.name.underscore.sub(/_controller$/, '') 
    178179          child.layout(layout_match) unless layout_list.grep(%r{layouts/#{layout_match}\.[a-z][0-9a-z]*$}).empty? 
  • trunk/actionpack/lib/action_controller/test_process.rb

    r3443 r3493  
    332332          @response.template.assigns[key.to_s] 
    333333        end 
     334      end 
     335 
     336      def build_request_uri(action, parameters) 
     337        options = @controller.send(:rewrite_options, parameters) 
     338        options.update(:only_path => true, :action => action) 
     339        url = ActionController::UrlRewriter.new(@request, parameters) 
     340        @request.set_REQUEST_URI(url.rewrite(options)) 
    334341      end 
    335342 
  • trunk/actionpack/test/template/text_helper_test.rb

    r3359 r3493  
    44require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/numeric'  # for human_size 
    55require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/hash' # for stringify_keys 
    6 require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/object_and_class.rb' # for blank? 
     6require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/object.rb' # for blank? 
    77 
    88class TextHelperTest < Test::Unit::TestCase 
  • trunk/activerecord/lib/active_record/base.rb

    r3463 r3493  
    245245 
    246246    def self.inherited(child) #:nodoc: 
     247      child.send :include, Reloadable 
    247248      @@subclasses[self] ||= [] 
    248249      @@subclasses[self] << child 
  • trunk/activerecord/lib/active_record/observer.rb

    r2766 r3493  
    8282    include Singleton 
    8383 
     84    # Observer subclasses should be reloaded by the dispatcher in Rails 
     85    # when Dependencies.mechanism = :load. 
     86    def self.inherited(child) #:nodoc: 
     87      child.send :include, Reloadable 
     88      super 
     89    end 
     90 
    8491    # Attaches the observer to the supplied model classes. 
    8592    def self.observe(*models) 
  • trunk/activerecord/test/class_inheritable_attributes_test.rb

    r2691 r3493  
    11require 'test/unit' 
    22require 'abstract_unit' 
    3 require 'active_support/class_inheritable_attributes' 
     3require 'active_support/core_ext/class/inheritable_attributes' 
    44 
    55class A 
  • trunk/activesupport/CHANGELOG

    r3469 r3493  
    11*SVN* 
     2 
     3* Added reusable reloading support through the inclusion of the Relodable module that all subclasses of ActiveRecord::Base, ActiveRecord::Observer, ActiveController::Base, and ActionMailer::Base automatically gets. This means that these classes will be reloaded by the dispatcher when Dependencies.mechanism = :load. You can make your own models reloadable easily: 
     4 
     5    class Setting 
     6      include Reloadable 
     7    end 
     8   
     9  Reloading a class is done by removing its constant which will cause it to be loaded again on the next reference. [DHH] 
     10 
     11* Added auto-loading support for classes in modules, so Conductor::Migration will look for conductor/migration.rb and Conductor::Database::Settings will look for conductor/database/settings.rb [Nicholas Seckar] 
    212 
    313* Add Object#instance_exec, like instance_eval but passes its arguments to the block.  (Active Support will not override the Ruby 1.9 implementation of this method.) [Sam Stephenson] 
  • trunk/activesupport/lib/active_support.rb

    r3356 r3493  
    2424$:.unshift(File.dirname(__FILE__)) 
    2525 
    26 require 'active_support/class_attribute_accessors' 
    27 require 'active_support/class_inheritable_attributes' 
    2826require 'active_support/inflector' 
    2927 
     
    3129require 'active_support/clean_logger' 
    3230require 'active_support/dependencies' 
     31require 'active_support/reloadable' 
    3332 
    3433require 'active_support/ordered_options' 
  • trunk/activesupport/lib/active_support/clean_logger.rb

    r3130 r3493  
    11require 'logger' 
    2 require File.dirname(__FILE__) + '/class_attribute_accessors' 
     2require File.dirname(__FILE__) + '/core_ext/class/attribute_accessors' 
    33 
    44class Logger #:nodoc: 
  • trunk/activesupport/lib/active_support/core_ext/blank.rb

    r2853 r3493  
    1 # The methods here are provided to speed up function blank? in class Object 
     1class Object #:nodoc: 
     2  # "", "   ", nil, [], and {} are blank 
     3  def blank? 
     4    if respond_to?(:empty?) && respond_to?(:strip) 
     5      empty? or strip.empty? 
     6    elsif respond_to?(:empty?) 
     7      empty? 
     8    else 
     9      !self 
     10    end 
     11  end 
     12end 
     13 
    214class NilClass #:nodoc: 
    315  def blank? 
  • trunk/activesupport/lib/active_support/core_ext/exception.rb

    r2676 r3493  
    11class Exception 
    2    
    32  alias :clean_message :message 
    43   
  • trunk/activesupport/lib/active_support/dependencies.rb

    r3193 r3493  
    11require 'set' 
    2 require File.dirname(__FILE__) + '/module_attribute_accessors' 
     2require File.dirname(__FILE__) + '/core_ext/module/attribute_accessors' 
    33require File.dirname(__FILE__) + '/core_ext/load_error' 
    44require File.dirname(__FILE__) + '/core_ext/kernel' 
     
    7070  end 
    7171 
    72   def remove_subclasses_for(*classes) 
    73     Object.remove_subclasses_of(*classes) 
    74   end 
    75    
    7672  # LoadingModules implement namespace-safe dynamic loading. 
    7773  # They support automatic loading via const_missing, allowing contained items to be automatically 
     
    212208  # Rename the original handler so we can chain it to the new one 
    213209  alias :rails_original_const_missing :const_missing 
    214  
     210   
     211  def parent 
     212    parent_name = name.split('::')[0..-2] * '::' 
     213    parent_name.empty? ? Object : parent_name.constantize 
     214  end 
     215   
     216  def as_load_path 
     217    if self == Object || self == Kernel 
     218      '' 
     219    elsif is_a? Class 
     220      parent == self ? '' : parent.as_load_path 
     221    else 
     222      name.split('::').collect do |word| 
     223        word.underscore 
     224      end * '/' 
     225    end 
     226  end 
     227   
    215228  # Use const_missing to autoload associations so we don't have to 
    216229  # require_association when using single-table inheritance. 
    217230  def const_missing(class_id) 
    218     if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id) 
     231    if Object.const_defined?(:Controllers) && Object::Controllers.const_available?(class_id) 
    219232      return Object::Controllers.const_get(class_id) 
    220233    end 
    221234     
    222235    file_name = class_id.to_s.demodulize.underscore 
     236    file_path = as_load_path.empty? ? file_name : "#{as_load_path}/#{file_name}" 
    223237    begin 
    224       require_dependency(file_name) 
    225       raise NameError.new("uninitialized constant #{class_id}") unless Object.const_defined?(class_id) 
    226       return Object.const_get(class_id) 
     238      require_dependency(file_path) 
     239      brief_name = self == Object ? '' : "#{name}::" 
     240      raise NameError.new("uninitialized constant #{brief_name}#{class_id}") unless const_defined?(class_id) 
     241      return const_get(class_id) 
    227242    rescue MissingSourceFile => e 
    228       # Convert the exception to a NameError only if the file we are looking for is the missing one. 
    229       raise unless e.is_missing? file_name 
     243      # Re-raise the error if it does not concern the file we were trying to load. 
     244      raise unless e.is_missing? file_path 
     245       
     246      # Look for a directory in the load path that we ought to load. 
     247      if $LOAD_PATH.any? { |base| File.directory? "#{base}/#{file_path}" } 
     248        mod = Module.new 
     249        const_set class_id, mod # Create the new module 
     250        return mod 
     251      end 
     252       
     253      if parent && parent != self 
     254        suppress(NameError) do 
     255          return parent.send(:const_missing, class_id) 
     256        end 
     257      end 
     258       
    230259      raise NameError.new("uninitialized constant #{class_id}").copy_blame!(e) 
     260    end 
     261  end 
     262end 
     263 
     264class Class 
     265  def const_missing(class_id) 
     266    if [Object, Kernel].include?(self) || parent == self 
     267      super 
     268    else 
     269      parent.send :const_missing, class_id 
    231270    end 
    232271  end 
  • trunk/activesupport/test/class_inheritable_attributes_test.rb

    r624 r3493  
    11require 'test/unit' 
    2 require File.dirname(__FILE__) + '/../lib/active_support/class_inheritable_attributes' 
     2require File.dirname(__FILE__) + '/../lib/active_support/core_ext/class/inheritable_attributes' 
    33 
    44class ClassInheritableAttributesTest < Test::Unit::TestCase 
  • trunk/activesupport/test/core_ext/blank_test.rb

    r2849 r3493  
    11require 'test/unit' 
    2 require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/object_and_class
     2require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/object
    33require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/blank' 
    44 
  • trunk/activesupport/test/core_ext/object_and_class_ext_test.rb

    r3469 r3493  
    11require 'test/unit' 
    2 require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/object_and_class' 
     2require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/object' 
     3require File.dirname(__FILE__) + '/../../lib/active_support/core_ext/class' 
    34 
    45class ClassA; end 
  • trunk/activesupport/test/dependencies_test.rb

    r3190 r3493  
    11require 'test/unit' 
    22$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib/active_support/' 
     3require 'core_ext/string' 
    34require 'dependencies' 
    45 
     
    100101    Dependencies.mechanism = old_mechanism 
    101102  end 
     103   
     104  def test_as_load_path 
     105    assert_equal '', DependenciesTest.as_load_path 
     106  end 
     107   
     108  def test_module_loading 
     109    $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/autoloading_fixtures" 
     110    old_mechanism, Dependencies.mechanism = Dependencies.mechanism, :load 
     111     
     112    assert_kind_of Module, A 
     113    assert_kind_of Class, A::B 
     114    assert_kind_of Class, A::C::D 
     115  ensure 
     116    $LOAD_PATH.shift 
     117    Dependencies.mechanism = old_mechanism 
     118  end 
    102119end 
  • trunk/activesupport/test/option_merger_test.rb

    r3458 r3493  
    33unless defined? ActiveSupport::OptionMerger 
    44  require File.dirname(__FILE__) + '/../lib/active_support/option_merger' 
    5   require File.dirname(__FILE__) + '/../lib/active_support/core_ext/object_and_class
     5  require File.dirname(__FILE__) + '/../lib/active_support/core_ext/object
    66end 
    77 
  • trunk/railties/lib/dispatcher.rb

    r3218 r3493  
    5454      Dependencies.clear 
    5555      ActiveRecord::Base.reset_subclasses 
    56       Dependencies.remove_subclasses_for(ActiveRecord::Base, ActiveRecord::Observer, ActionController::Base) 
    57       Dependencies.remove_subclasses_for(ActionMailer::Base) if defined?(ActionMailer::Base) 
     56      Reloadable.remove_classes_including 
    5857    end 
    5958