Changeset 4501
- Timestamp:
- 06/28/06 18:11:35 (2 years ago)
- Files:
-
- branches/stable/actionpack/CHANGELOG (modified) (1 diff)
- branches/stable/actionpack/lib/action_controller/routing.rb (modified) (2 diffs)
- branches/stable/actionpack/test/controller/routing_test.rb (modified) (2 diffs)
- branches/stable/actionpack/test/fixtures/application_root (added)
- branches/stable/actionpack/test/fixtures/application_root/app (added)
- branches/stable/actionpack/test/fixtures/application_root/app/controllers (added)
- branches/stable/actionpack/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller (added)
- branches/stable/actionpack/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb (added)
- branches/stable/actionpack/test/fixtures/application_root/app/controllers/module_that_holds_controllers (added)
- branches/stable/actionpack/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb (added)
- branches/stable/actionpack/test/fixtures/application_root/app/models (added)
- branches/stable/actionpack/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/stable/actionpack/CHANGELOG
r4496 r4501 1 * Fix broken traverse_to_controller. We now: 2 Look for a _controller.rb file under RAILS_ROOT to load. 3 If we find it, we require_dependency it and return the controller it defined. (If none was defined we stop looking.) 4 If we don't find it, we look for a .rb file under RAILS_ROOT to load. If we find it, and it loads a constant we keep looking. 5 Otherwise we check to see if a directory of the same name exists, and if it does we create a module for it. 6 7 1 8 *1.12.2* (June 27th, 2006) 2 9 branches/stable/actionpack/lib/action_controller/routing.rb
r4458 r4501 225 225 index = start_at 226 226 mod_name = controller_name = segment = nil 227 228 227 while index < length 229 228 return nil unless /\A[A-Za-z][A-Za-z\d_]*\Z/ =~ (segment = segments[index]) … … 232 231 mod_name = segment.camelize 233 232 controller_name = "#{mod_name}Controller" 233 path_suffix = File.join(segments[start_at..(index - 1)]) 234 next_mod = nil 234 235 235 begin 236 # We use eval instead of const_get to avoid obtaining values from parent modules. 237 controller = eval("mod::#{controller_name}", nil, __FILE__, __LINE__) 238 expected_name = "#{mod.name}::#{controller_name}" 239 240 # Detect the case when const_get returns an object from a parent namespace. 241 if controller.is_a?(Class) && controller.ancestors.include?(ActionController::Base) && (mod == Object || controller.name == expected_name) 242 return controller, (index - start_at) 243 end 244 rescue NameError => e 245 raise unless /^uninitialized constant .*#{controller_name}$/ =~ e.message 236 # If the controller is already present, or if we load it, return it. 237 if mod.const_defined?(controller_name) || attempt_load(mod, controller_name, path_suffix + "_controller") == :defined 238 controller = mod.const_get(controller_name) 239 return nil unless controller.is_a?(Class) && controller.ancestors.include?(ActionController::Base) # it's not really a controller? 240 return [controller, (index - start_at)] 246 241 end 247 242 243 # No controller? Look for the module 248 244 if mod.const_defined? mod_name 249 245 next_mod = mod.send(:const_get, mod_name) 250 246 next_mod = nil unless next_mod.is_a?(Module) 251 247 else 252 suffix = File.join(segments[start_at..index]) 253 $:.each do |base| 254 path = File.join(base, suffix) 255 next unless File.directory? path 256 next_mod = Module.new 257 mod.send(:const_set, mod_name, next_mod) 258 break 248 # Try to load a file that defines the module we want. 249 case attempt_load(mod, mod_name, path_suffix) 250 when :defined then next_mod = mod.const_get mod_name 251 when :dir then # We didn't find a file, but there's a dir. 252 next_mod = Module.new # So create a module for the directory 253 mod.send :const_set, mod_name, next_mod 254 else 255 return nil 259 256 end 260 257 end 261 258 mod = next_mod 262 259 263 return nil unless mod 264 end 260 return nil unless mod && mod.is_a?(Module) 261 end 262 nil 263 end 264 265 protected 266 267 def safe_load_paths #:nodoc: 268 if defined?(RAILS_ROOT) 269 $LOAD_PATH.select do |base| 270 base = File.expand_path(base) 271 extended_root = File.expand_path(RAILS_ROOT) 272 base[0, extended_root.length] == extended_root 273 end 274 else 275 $LOAD_PATH 276 end 277 end 278 279 def attempt_load(mod, const_name, path) 280 has_dir = false 281 safe_load_paths.each do |load_path| 282 full_path = File.join(load_path, path) 283 file_path = full_path + '.rb' 284 if File.file?(file_path) # Found a .rb file? Load it up 285 require_dependency(file_path) 286 return :defined if mod.const_defined? const_name 287 else 288 has_dir ||= File.directory?(full_path) 289 end 290 end 291 return (has_dir ? :dir : nil) 265 292 end 266 293 end branches/stable/actionpack/test/controller/routing_test.rb
r4457 r4501 978 978 base = File.dirname(File.dirname(File.expand_path(__FILE__))) 979 979 $: << File.join(base, 'fixtures') 980 Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') 980 981 assert_equal nil, ActionController::Routing::ControllerComponent.traverse_to_controller(%w(dont_load pretty please)) 981 982 ensure 982 983 $:[0..-1] = load_path 984 Object.send :remove_const, :RAILS_ROOT 983 985 end 984 986 … … 987 989 end 988 990 991 # This is evil, but people do it. 992 def test_traverse_to_controller_should_pass_thru_classes 993 load_path = $:.dup 994 base = File.dirname(File.dirname(File.expand_path(__FILE__))) 995 $: << File.join(base, 'fixtures') 996 $: << File.join(base, 'fixtures/application_root/app/controllers') 997 $: << File.join(base, 'fixtures/application_root/app/models') 998 Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') 999 pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(a_class_that_contains_a_controller poorly_placed)) 1000 1001 # Make sure the container class was loaded properly 1002 assert defined?(AClassThatContainsAController) 1003 assert_kind_of Class, AClassThatContainsAController 1004 assert_equal :you_know_it, AClassThatContainsAController.is_special? 1005 1006 # Make sure the controller was too 1007 assert_kind_of Array, pair 1008 assert_equal 2, pair[1] 1009 klass = pair.first 1010 assert_kind_of Class, klass 1011 assert_equal :decidedly_so, klass.is_evil? 1012 assert klass.ancestors.include?(ActionController::Base) 1013 assert defined?(AClassThatContainsAController::PoorlyPlacedController) 1014 assert_equal klass, AClassThatContainsAController::PoorlyPlacedController 1015 ensure 1016 $:[0..-1] = load_path 1017 Object.send :remove_const, :RAILS_ROOT 1018 end 1019 1020 def test_traverse_to_nested_controller 1021 load_path = $:.dup 1022 base = File.dirname(File.dirname(File.expand_path(__FILE__))) 1023 $: << File.join(base, 'fixtures') 1024 $: << File.join(base, 'fixtures/application_root/app/controllers') 1025 Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root') 1026 pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(module_that_holds_controllers nested)) 1027 1028 assert_not_equal nil, pair 1029 1030 # Make sure that we created a module for the dir 1031 assert defined?(ModuleThatHoldsControllers) 1032 assert_kind_of Module, ModuleThatHoldsControllers 1033 1034 # Make sure the controller is ok 1035 assert_kind_of Array, pair 1036 assert_equal 2, pair[1] 1037 klass = pair.first 1038 assert_kind_of Class, klass 1039 assert klass.ancestors.include?(ActionController::Base) 1040 assert defined?(ModuleThatHoldsControllers::NestedController) 1041 assert_equal klass, ModuleThatHoldsControllers::NestedController 1042 ensure 1043 $:[0..-1] = load_path 1044 Object.send :remove_const, :RAILS_ROOT 1045 end 1046 989 1047 end 990 1048