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

Changeset 614

Show
Ignore:
Timestamp:
02/15/05 00:51:02 (4 years ago)
Author:
david
Message:

Merged back the Routing branch

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/lib/action_controller

    • Property svn:externals changed from
      support http://dev.rubyonrails.org/svn/rails/trunk/activesupport/lib
      to
      support http://dev.rubyonrails.org/svn/rails/branches/routing/activesupport/lib
  • trunk/actionpack/lib/action_controller/assertions/action_pack_assertions.rb

    r525 r614  
    142142        end 
    143143      end 
    144  
     144       
    145145      # ensure our redirection url is an exact match 
    146146      def assert_redirect_url(url=nil, message=nil) 
     
    157157        msg = build_message(message, "<?> was not found in the location: <?>", pattern, response.redirect_url) 
    158158        assert_block(msg) { response.redirect_url_match?(pattern) } 
     159      end 
     160 
     161      # -- routing assertions -------------------------------------------------- 
     162 
     163      # Asserts that the routing of the given path is handled correctly and that the parsed options match. 
     164      # Also verifies that the provided options can be used to generate the provided path. 
     165      def assert_routing(path, options, defaults={}, extras={}, message=nil) 
     166        defaults[:controller] ||= options[:controller] # Assume given controller, 
     167        request = ActionController::TestRequest.new({}, {}, nil) 
     168        request.path_parameters = defaults 
     169         
     170        ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty? # Load routes.rb if it hasn't been loaded. 
     171         
     172        generated_path, found_extras = ActionController::Routing::Routes.generate(defaults.merge(options), request) 
     173        generated_path = generated_path.join('/') 
     174        msg = build_message(message, "found extras <?>, not <?>", found_extras, extras) 
     175        assert_block(msg) { found_extras == extras } 
     176         
     177        msg = build_message(message, "The generated path <?> did not match <?>", generated_path, path) 
     178        assert_block(msg) { path == generated_path } 
     179         
     180        request = ActionController::TestRequest.new({}, {}, nil) 
     181        request.path = path 
     182        ActionController::Routing::Routes.recognize!(request) 
     183         
     184        expected_options = options.clone 
     185        extras.each {|k,v| expected_options.delete k} 
     186         
     187        msg = build_message(message, "The recognized options <?> did not match <?>", request.path_parameters, expected_options) 
     188        assert_block(msg) { request.path_parameters == expected_options } 
    159189      end 
    160190 
  • trunk/actionpack/lib/action_controller/base.rb

    r525 r614  
    1313  end 
    1414  class MissingTemplate < ActionControllerError #:nodoc: 
     15  end 
     16  class RoutingError < ActionControllerError 
     17    attr_reader :failures 
     18    def initialize(message, failures=[]) 
     19      super(message) 
     20      @failures = failures 
     21    end 
    1522  end 
    1623  class UnknownAction < ActionControllerError #:nodoc: 
     
    206213    @@consider_all_requests_local = true 
    207214    cattr_accessor :consider_all_requests_local 
     215     
     216    # Enable or disable the collection of failure information for RoutingErrors. 
     217    # This information can be extremely useful when tweaking custom routes, but is 
     218    # pointless once routes have been tested and verified. 
     219    @@debug_routes = true 
     220    cattr_accessor :debug_routes 
    208221 
    209222    # Template root determines the base from which template references will be made. So a call to render("test/template") 
     
    261274      def controller_name 
    262275        Inflector.underscore(controller_class_name.sub(/Controller/, "")) 
     276      end 
     277       
     278      # Convert the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat". 
     279      def controller_path 
     280        components = self.name.to_s.split('::').collect { |name| name.underscore } 
     281        components[-1] = $1 if /^(.*)_controller$/ =~ components[-1] 
     282        components.shift if components.first == 'controllers' # Transitional conditional to accomodate root Controllers module 
     283        components.join('/') 
    263284      end 
    264285    end 
     
    336357          when Hash   then @url.rewrite(rewrite_options(options)) 
    337358        end 
    338       end 
    339  
    340       def module_name 
    341         @params["module"] 
    342359      end 
    343360 
     
    692709 
    693710      def default_template_name(default_action_name = action_name) 
    694         module_name ? "#{module_name}/#{controller_name}/#{default_action_name}" : "#{controller_name}/#{default_action_name}" 
     711        "#{self.class.controller_path}/#{default_action_name}" 
    695712      end 
    696713  end 
  • trunk/actionpack/lib/action_controller/cgi_process.rb

    r502 r614  
    4747    end 
    4848 
     49    def query_string 
     50      return @cgi.query_string unless @cgi.query_string.nil? || @cgi.query_string.empty? 
     51      parts = env['REQUEST_URI'].split('?') 
     52      parts.shift 
     53      return parts.join('?') 
     54    end 
     55 
    4956    def query_parameters 
    50       @cgi.query_string ? CGIMethods.parse_query_parameters(@cgi.query_string) : {} 
     57      qs = self.query_string 
     58      qs.empty? ? {} : CGIMethods.parse_query_parameters(query_string) 
    5159    end 
    5260 
  • trunk/actionpack/lib/action_controller/helpers.rb

    r514 r614  
    4949        args.flatten.each do |arg| 
    5050          case arg 
    51           when Module 
    52             add_template_helper(arg) 
    53           when String, Symbol 
    54             file_name  = Inflector.underscore(arg.to_s.downcase) + '_helper' 
    55             class_name = Inflector.camelize(file_name) 
    56             begin 
    57               require_dependency(file_name) 
    58             rescue LoadError => load_error 
    59               requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] 
    60               if requiree == file_name 
    61                 raise LoadError, "Missing helper file helpers/#{file_name}.rb" 
    62               else 
    63                 raise LoadError, "Can't load file: #{requiree}" 
     51            when Module 
     52              add_template_helper(arg) 
     53            when String, Symbol 
     54              file_name  = arg.to_s.underscore + '_helper' 
     55              class_name = file_name.camelize 
     56 
     57              begin 
     58                require_dependency(file_name) 
     59              rescue LoadError => load_error 
     60                requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1] 
     61                raise LoadError, requiree == file_name ? "Missing helper file helpers/#{file_name}.rb" : "Can't load file: #{requiree}" 
    6462              end 
    65             end 
    66             raise ArgumentError, "Missing #{class_name} module in helpers/#{file_name}.rb" unless Object.const_defined?(class_name) 
    67             add_template_helper(Object.const_get(class_name)) 
    68           else 
    69             raise ArgumentError, 'helper expects String, Symbol, or Module argument' 
     63 
     64              add_template_helper(class_name.constantize) 
     65            else 
     66              raise ArgumentError, 'helper expects String, Symbol, or Module argument' 
    7067          end 
    7168        end 
     
    9693          inherited_without_helper(child) 
    9794          begin 
    98             child.helper(child.controller_name
     95            child.helper(child.controller_path
    9996          rescue ArgumentError, LoadError 
    10097            # No default helper available for this controller 
  • trunk/actionpack/lib/action_controller/request.rb

    r525 r614  
    44    # Returns both GET and POST parameters in a single hash. 
    55    def parameters 
    6       @parameters ||= request_parameters.update(query_parameters) 
     6      @parameters ||= request_parameters.merge(query_parameters).merge(path_parameters).with_indifferent_access 
    77    end 
    88 
     
    7474     
    7575    def request_uri 
    76       env['REQUEST_URI'] 
     76      (%r{^\w+\://[^/]+(/.*|$)$} =~ env['REQUEST_URI']) ? $1 : env['REQUEST_URI'] # Remove domain, which webrick puts into the request_uri. 
    7777    end 
    7878 
     
    8686 
    8787    def path 
    88       request_uri ? request_uri.split('?').first : '' 
     88      path = request_uri ? request_uri.split('?').first : '' 
    8989    end 
    9090 
     
    101101      env['HTTP_HOST'] || host + port_string 
    102102    end 
     103   
     104    def path_parameters=(parameters) 
     105      @path_parameters = parameters 
     106      @parameters = nil 
     107    end 
    103108 
     109    def path_parameters 
     110      @path_parameters ||= {} 
     111    end 
     112     
    104113    #-- 
    105114    # Must be implemented in the concrete request 
  • trunk/actionpack/lib/action_controller/rescue.rb

    r525 r614  
    4949      # Overwrite to implement public exception handling (for requests answering false to <tt>local_request?</tt>). 
    5050      def rescue_action_in_public(exception) #:doc: 
    51         render_text "<html><body><h1>Application error (Rails)</h1></body></html>" 
     51        case exception 
     52          when RoutingError, UnknownAction then 
     53            render_text(IO.read(File.join(RAILS_ROOT, 'public', '404.html')), "404 Not Found") 
     54          else render_text "<html><body><h1>Application error (Rails)</h1></body></html>" 
     55        end 
    5256      end 
    5357 
     
    111115          case exception 
    112116            when MissingTemplate then "missing_template" 
     117            when RoutingError then "routing_error" 
    113118            when UnknownAction   then "unknown_action" 
    114119            when ActionView::TemplateError then "template_error" 
    115             else "diagnostics" 
     120            else raise ;"diagnostics" 
    116121          end 
    117122        ) 
     123      end 
     124       
     125      def response_code_for_rescue(exception) 
     126        case exception 
     127          when UnknownAction, RoutingError then "404 Page Not Found" 
     128          else "500 Internal Error" 
     129        end 
    118130      end 
    119131       
  • trunk/actionpack/lib/action_controller/scaffolding.rb

    r525 r614  
    150150          private 
    151151            def render#{suffix}_scaffold(action = caller_method_name(caller)) 
    152               if template_exists?("\#{controller_name}/\#{action}") 
     152              if template_exists?("\#{self.class.controller_path}/\#{action}") 
    153153                render_action(action) 
    154154              else 
  • trunk/actionpack/lib/action_controller/test_process.rb

    r587 r614  
    3232  class TestRequest < AbstractRequest #:nodoc: 
    3333    attr_accessor :cookies 
    34     attr_accessor :query_parameters, :request_parameters, :session, :env 
    35     attr_accessor :host, :path, :request_uri, :remote_addr 
     34    attr_accessor :query_parameters, :request_parameters, :path, :session, :env 
     35    attr_accessor :host, :remote_addr 
    3636 
    3737    def initialize(query_parameters = nil, request_parameters = nil, session = nil) 
     
    5959    end 
    6060     
     61    # Used to check AbstractRequest's request_uri functionality. 
     62    # Disables the use of @path and @request_uri so superclass can handle those. 
     63    def set_REQUEST_URI(value) 
     64      @env["REQUEST_URI"] = value 
     65      @request_uri = nil 
     66      @path = nil 
     67    end 
     68 
    6169    def request_uri=(uri) 
    6270      @request_uri = uri 
    6371      @path = uri.split("?").first 
    6472    end 
     73 
     74    def request_uri 
     75      @request_uri || super() 
     76    end 
     77 
     78    def path 
     79      @path || super() 
     80    end 
     81     
    6582 
    6683    private 
     
    238255          @request.env['REQUEST_METHOD'] ||= "GET" 
    239256          @request.action = action.to_s 
     257          @request.path_parameters = { :controller => @controller.class.controller_path } 
    240258          @request.parameters.update(parameters) unless parameters.nil? 
    241259          @request.session = ActionController::TestSession.new(session) unless session.nil? 
  • trunk/actionpack/lib/action_controller/url_rewriter.rb

    r580 r614  
    22  # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. 
    33  class UrlRewriter #:nodoc: 
    4     VALID_OPTIONS = [:action, :action_prefix, :action_suffix, :application_prefix, :module, :controller, :controller_prefix, :anchor, :params, :path_params, :id, :only_path, :overwrite_params, :host, :protocol ] 
    5    
    6     def initialize(request, controller, action) 
    7       @request, @controller, @action = request, controller, action 
     4    RESERVED_OPTIONS = [:anchor, :params, :path_params, :only_path, :host, :protocol] 
     5    def initialize(request, parameters) 
     6      @request, @parameters = request, parameters 
    87      @rewritten_path = @request.path ? @request.path.dup : "" 
    98    end 
     
    2322 
    2423    def to_str 
    25       "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@controller}, #{@action}, #{@request.parameters.inspect}" 
     24               "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@parameters[:controller]}, #{@parameters[:action]}, #{@request.parameters.inspect}" 
    2625    end 
    2726 
     
    4948      end 
    5049 
    51       def rewrite_path(path, options) 
    52         include_id_in_path_params(options) 
    53  
    54         path = rewrite_action(path, options)      if options[:action] || options[:action_prefix] 
    55         path = rewrite_path_params(path, options) if options[:path_params] 
    56         path = rewrite_controller(path, options)  if options[:controller] || options[:controller_prefix] 
     50      def rewrite_path(options) 
     51        options = options.symbolize_keys 
     52        RESERVED_OPTIONS.each {|k| options.delete k} 
     53         
     54        path, extras = Routing::Routes.generate(options, @request) 
     55        path = "/#{path.join('/')}" 
     56        path += build_query_string(extras) 
     57         
    5758        return path 
    5859      end 
  • trunk/actionpack/lib/action_view/partials.rb

    r525 r614  
    6161          return File.dirname(partial_path), File.basename(partial_path) 
    6262        else 
    63           return controller.send(:controller_name), partial_path 
     63          return controller.class.controller_path, partial_path 
    6464        end 
    6565      end 
  • trunk/actionpack/test/controller/cookie_test.rb

    r22 r614  
    2727      cookies["login"]     = "XJ-122" 
    2828      render_text "hello world" 
    29     end 
    30  
    31     def access_frozen_cookies 
    32       @cookies["wont"] = "work" 
    3329    end 
    3430 
     
    6864  end 
    6965 
    70   def test_setting_cookie_on_frozen_instance_variable 
    71     @request.action = "access_frozen_cookies" 
    72     assert_raises(TypeError) { process_request } 
    73   end 
    74  
    7566  private 
    7667    def process_request 
  • trunk/actionpack/test/controller/helper_test.rb

    r250 r614  
    11require File.dirname(__FILE__) + '/../abstract_unit' 
     2$:.unshift(File.dirname(__FILE__) + '/../fixtures/helpers') 
     3 
     4class TestController < ActionController::Base 
     5  attr_accessor :delegate_attr 
     6  def delegate_method() end 
     7  def rescue_action(e) raise end 
     8end 
     9 
     10module Fun 
     11  class GamesController < ActionController::Base 
     12    def render_hello_world 
     13      render_template "hello: <%= stratego %>" 
     14    end 
     15 
     16    def rescue_action(e) raise end 
     17  end 
     18end 
     19 
     20module LocalAbcHelper 
     21  def a() end 
     22  def b() end 
     23  def c() end 
     24end 
    225 
    326class HelperTest < Test::Unit::TestCase 
    427  HELPER_PATHS = %w(/../fixtures/helpers) 
    5  
    6   class TestController < ActionController::Base 
    7     attr_accessor :delegate_attr 
    8     def delegate_method() end 
    9     def rescue_action(e) raise end 
    10   end 
    11  
    12   module LocalAbcHelper 
    13     def a() end 
    14     def b() end 
    15     def c() end 
    16   end 
    17  
    1828 
    1929  def setup 
     
    103113  end 
    104114 
     115  def test_helper_for_nested_controller 
     116    @request    = ActionController::TestRequest.new 
     117    @response   = ActionController::TestResponse.new 
     118    @request.action = "render_hello_world" 
     119     
     120    assert_equal "hello: Iz guuut!", Fun::GamesController.process(@request, @response).body 
     121  end 
    105122 
    106123  private 
  • trunk/actionpack/test/controller/render_test.rb

    r351 r614  
    33Customer = Struct.new("Customer", :name) 
    44 
    5 class RenderTest < Test::Unit::TestCase 
    6   class TestController < ActionController::Base 
    7     layout :determine_layout 
    8  
     5module Fun 
     6  class GamesController < ActionController::Base 
    97    def hello_world 
    108    end 
     9  end 
     10end 
    1111 
    12     def render_hello_world 
    13       render "test/hello_world" 
    14     end 
    1512 
    16     def render_hello_world_from_variable 
    17       @person = "david" 
    18       render_text "hello #{@person}" 
    19     end 
     13class TestController < ActionController::Base 
     14  layout :determine_layout 
    2015 
    21     def render_action_hello_world 
    22       render_action "hello_world" 
    23     end 
    24      
    25     def render_text_hello_world 
    26       render_text "hello world" 
    27     end 
    28  
    29     def render_custom_code 
    30       render_text "hello world", "404 Moved" 
    31     end 
    32      
    33     def render_xml_hello 
    34       @name = "David" 
    35       render "test/hello" 
    36     end 
    37  
    38     def greeting 
    39       # let's just rely on the template 
    40     end 
    41  
    42     def layout_test 
    43       render_action "hello_world" 
    44     end 
    45      
    46     def builder_layout_test 
    47       render_action "hello" 
    48     end 
    49  
    50     def partials_list 
    51       @customers = [ Customer.new("david"), Customer.new("mary") ] 
    52       render_action "list" 
    53     end 
    54  
    55     def modgreet 
    56     end 
    57  
    58     def rescue_action(e) raise end 
    59        
    60     private 
    61       def determine_layout 
    62         case action_name  
    63           when "layout_test":         "layouts/standard" 
    64           when "builder_layout_test": "layouts/builder" 
    65         end 
    66       end 
     16  def hello_world 
    6717  end 
    6818 
    69   TestController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
    70    
    71   class TestLayoutController < ActionController::Base 
    72     layout "layouts/standard" 
    73      
    74     def hello_world 
    75     end 
    76      
    77     def hello_world_outside_layout 
    78     end 
    79  
    80     def rescue_action(e) 
    81       raise unless ActionController::MissingTemplate === e 
    82     end 
     19  def render_hello_world 
     20    render "test/hello_world" 
    8321  end 
    8422 
     23  def render_hello_world_from_variable 
     24    @person = "david" 
     25    render_text "hello #{@person}" 
     26  end 
     27 
     28  def render_action_hello_world 
     29    render_action "hello_world" 
     30  end 
     31   
     32  def render_text_hello_world 
     33    render_text "hello world" 
     34  end 
     35 
     36  def render_custom_code 
     37    render_text "hello world", "404 Moved" 
     38  end 
     39   
     40  def render_xml_hello 
     41    @name = "David" 
     42    render "test/hello" 
     43  end 
     44 
     45  def greeting 
     46    # let's just rely on the template 
     47  end 
     48 
     49  def layout_test 
     50    render_action "hello_world" 
     51  end 
     52   
     53  def builder_layout_test 
     54    render_action "hello" 
     55  end 
     56 
     57  def partials_list 
     58    @customers = [ Customer.new("david"), Customer.new("mary") ] 
     59    render_action "list" 
     60  end 
     61 
     62  def rescue_action(e) raise end 
     63     
     64  private 
     65    def determine_layout 
     66      case action_name  
     67        when "layout_test":         "layouts/standard" 
     68        when "builder_layout_test": "layouts/builder" 
     69      end 
     70    end 
     71end 
     72 
     73TestController.template_root = File.dirname(__FILE__) + "/../fixtures/" 
     74 
     75class TestLayoutController < ActionController::Base 
     76  layout "layouts/standard" 
     77   
     78  def hello_world 
     79  end 
     80   
     81  def hello_world_outside_layout 
     82  end 
     83 
     84  def rescue_action(e) 
     85    raise unless ActionController::MissingTemplate === e 
     86  end 
     87end 
     88 
     89class RenderTest < Test::Unit::TestCase 
    8590  def setup 
    8691    @request    = ActionController::TestRequest.new 
     
    171176  end 
    172177 
    173   def test_module_rendering 
    174     @request.action = "modgreet" 
    175     @request.parameters["module"] = "scope" 
    176     assert_equal "<p>Beautiful modules!</p>", process_request.body 
     178  def test_nested_rendering 
     179    @request.action = "hello_world" 
     180    assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body 
    177181  end 
    178182 
  • trunk/actionpack/test/controller/request_test.rb

    r214 r614  
    3232    assert_equal ":8080", @request.port_string 
    3333  end 
     34   
     35  def test_request_uri 
     36    @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri?mapped=1" 
     37    assert_equal "/path/of/some/uri?mapped=1", @request.request_uri 
     38    assert_equal "/path/of/some/uri", @request.path 
     39     
     40    @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri" 
     41    assert_equal "/path/of/some/uri", @request.request_uri 
     42    assert_equal "/path/of/some/uri", @request.path 
     43 
     44    @request.set_REQUEST_URI "/path/of/some/uri" 
     45    assert_equal "/path/of/some/uri", @request.request_uri 
     46    assert_equal "/path/of/some/uri", @request.path 
     47 
     48    @request.set_REQUEST_URI "/" 
     49    assert_equal "/", @request.request_uri 
     50    assert_equal "/", @request.path 
     51 
     52    @request.set_REQUEST_URI "/?m=b" 
     53    assert_equal "/?m=b", @request.request_uri 
     54    assert_equal "/", @request.path 
     55  end 
    3456 
    3557  def test_host_with_port 
  • trunk/activerecord/lib/active_record

    • Property svn:externals changed from
      support http://dev.rubyonrails.org/svn/rails/trunk/activesupport/lib
      to
      support http://dev.rubyonrails.org/svn/rails/branches/routing/activesupport/lib
  • trunk/activesupport/CHANGELOG

    r586 r614  
    22 
    33* Added IndifferentAccess as a way to wrap a hash by a symbol-based store that also can be accessed by string keys 
     4 
     5* Added Inflector.constantize to turn "Admin::User" into a reference for the constant Admin::User 
     6 
     7* Added that Inflector.camelize and Inflector.underscore can deal with modules like turning "Admin::User" into "admin/user" and back 
    48 
    59* Added Inflector.humanize to turn attribute names like employee_salary into "Employee salary". Used by automated error reporting in AR. 
  • trunk/activesupport/lib/core_ext/hash/indifferent_access.rb

    r581 r614  
    99  end 
    1010   
    11   alias_method :regular_read, :[] 
     11  alias_method :regular_reader, :[] unless method_defined?(:regular_reader) 
    1212   
    1313  def [](key) 
    1414    case key 
    15       when Symbol: regular_read(key) || regular_read(key.to_s) 
    16       when String: regular_read(key) || regular_read(key.to_sym) 
    17       else regular_read(key) 
     15      when Symbol: regular_reader(key) || regular_reader(key.to_s) 
     16      when String: regular_reader(key) || regular_reader(key.to_sym) 
     17      else regular_reader(key) 
    1818    end 
    1919  end 
    2020 
    21   alias_method :regular_writer, :[]= 
     21  alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) 
    2222   
    2323  def []=(key, value) 
  • trunk/activesupport/lib/core_ext/string/inflections.rb

    r450 r614  
    4040          Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) 
    4141        end 
     42 
     43        def constantize 
     44          Inflector.constantize(self) 
     45        end 
    4246      end 
    4347    end 
  • trunk/activesupport/lib/dependencies.rb

    r510 r614  
    33module Dependencies 
    44  extend self 
    5    
     5 
    66  @@loaded = [ ] 
    77  mattr_accessor :loaded 
     
    4242    classes.each { |klass| klass.remove_subclasses } 
    4343  end 
     44   
     45  # LoadingModules implement namespace-safe dynamic loading. 
     46  # They support automatic loading via const_missing, allowing contained items to be automatically 
     47  # loaded when required. No extra syntax is required, as expressions such as Controller::Admin::UserController 
     48  # load the relavent files automatically. 
     49  # 
     50  # Ruby-style modules are supported, as a folder named 'submodule' will load 'submodule.rb' when available. 
     51  class LoadingModule < Module 
     52    attr_reader :path 
     53 
     54    def initialize(filesystem_root, path=[]) 
     55      @path = path 
     56      @filesystem_root = filesystem_root 
     57    end 
     58 
     59    # The path to this module in the filesystem. 
     60    # Any subpath provided is taken to be composed of filesystem names. 
     61    def filesystem_path(subpath=[]) 
     62      File.join(@filesystem_root, self.path, subpath) 
     63    end 
     64 
     65    # Load missing constants if possible. 
     66    def const_missing(name) 
     67      return const_get(name) if const_defined?(name) == false && const_load!(name) 
     68      super(name) 
     69    end 
     70 
     71    # Load the controller class or a parent module. 
     72    def const_load!(name) 
     73      name = name.to_s if name.kind_of? Symbol 
     74 
     75      if File.directory? filesystem_path(name.underscore) 
     76        # Is it a submodule? If so, create a new LoadingModule *before* loading it. 
     77        # This ensures that subitems will be loadable 
     78        new_module = LoadingModule.new(@filesystem_root, self.path + [name.underscore]) 
     79        const_set(name, new_module) 
     80        Object.const_set(name, new_module) if @path.empty? 
     81      end 
     82       
     83      source_file = filesystem_path("#{(name == 'ApplicationController' ? 'Application' : name).underscore}.rb") 
     84      self.load_file(source_file) if File.file?(source_file) 
     85      self.const_defined?(name.camelize) 
     86    end 
     87 
     88    # Is this name present or loadable? 
     89    # This method is used by Routes to find valid controllers. 
     90    def const_available?(name) 
     91      name = name.to_s unless name.kind_of? String 
     92      File.directory?(filesystem_path(name.underscore)) || File.file?(filesystem_path("#{name.underscore}.rb")) 
     93    end 
     94 
     95    def clear 
     96      constants.each do |name| 
     97        Object.send(:remove_const, name) if Object.const_defined?(name) && @path.empty? 
     98        self.send(:remove_const, name) 
     99      end 
     100    end 
     101 
     102    def load_file(file_path) 
     103      Controllers.module_eval(IO.read(file_path), file_path, 1) # Hard coded Controller line here!!! 
     104    end 
     105  end 
    44106end 
    45107 
     
    53115    # require_association when using single-table inheritance. 
    54116    def const_missing(class_id) 
     117      if Object.const_defined?(:Controllers) and Object::Controllers.const_available?(class_id) 
     118        return Object::Controllers.const_get(class_id) 
     119      end 
    55120      begin 
    56121        require_or_load(class_id.to_s.demodulize.underscore) 
  • trunk/activesupport/lib/inflector.rb

    r525 r614  
    2121 
    2222  def camelize(lower_case_and_underscored_word) 
    23     lower_case_and_underscored_word.to_s.gsub(/(^|_)(.)/){$2.upcase
     23    lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase
    2424  end 
    2525   
    2626  def underscore(camel_cased_word) 
    27     camel_cased_word.to_s.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase 
     27    camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase 
    2828  end 
    2929 
     
    4848      (separate_class_name_and_id_with_underscore ? "_id" : "id") 
    4949  end 
    50    
     50 
     51  def constantize(camel_cased_word) 
     52    camel_cased_word.split("::").inject(Object) do |final_type, part|  
     53      final_type = final_type.const_get(part) 
     54    end 
     55  end 
     56 
    5157  private 
    5258    def plural_rules #:doc: 
  • trunk/activesupport/test/inflector_test.rb

    r449