aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activeresource/CHANGELOG2
-rw-r--r--activeresource/lib/active_resource/base.rb25
-rw-r--r--activeresource/test/base/load_test.rb35
3 files changed, 54 insertions, 8 deletions
diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG
index ee246042fd..94c10bb304 100644
--- a/activeresource/CHANGELOG
+++ b/activeresource/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* find_or_create_resource_for handles module nesting. #10646 [xavier]
+
* Allow setting ActiveResource::Base#format before #site. [rick]
* Support agnostic formats when calling custom methods. Closes #10635 [joerichsen]
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 76f4ca03db..25776265e9 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -845,17 +845,26 @@ module ActiveResource
find_or_create_resource_for(name.to_s.singularize)
end
+ # Tries to find a resource in a non empty list of nested modules
+ # Raises a NameError if it was not found in any of the given nested modules
+ def find_resource_in_modules(resource_name, module_names)
+ receiver = Object
+ namespaces = module_names[0, module_names.size-1].map do |module_name|
+ receiver = receiver.const_get(module_name)
+ end
+ if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
+ return namespace.const_get(resource_name)
+ else
+ raise NameError
+ end
+ end
+
# Tries to find a resource for a given name; if it fails, then the resource is created
def find_or_create_resource_for(name)
resource_name = name.to_s.camelize
-
- # FIXME: Make it generic enough to support any depth of module nesting
- if (ancestors = self.class.name.split("::")).size > 1
- begin
- ancestors.first.constantize.const_get(resource_name)
- rescue NameError
- self.class.const_get(resource_name)
- end
+ ancestors = self.class.name.split("::")
+ if ancestors.size > 1
+ find_resource_in_modules(resource_name, ancestors)
else
self.class.const_get(resource_name)
end
diff --git a/activeresource/test/base/load_test.rb b/activeresource/test/base/load_test.rb
index 622afb2fdf..944f337aed 100644
--- a/activeresource/test/base/load_test.rb
+++ b/activeresource/test/base/load_test.rb
@@ -10,6 +10,29 @@ module Highrise
class Comment < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000"
end
+
+ module Deeply
+ module Nested
+
+ class Note < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+ end
+
+ class Comment < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+ end
+
+ module TestDifferentLevels
+
+ class Note < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+ end
+
+ end
+
+ end
+ end
+
end
@@ -108,4 +131,16 @@ class BaseLoadTest < Test::Unit::TestCase
n = Highrise::Note.new(:comments => [{ :name => "1" }])
assert_kind_of Highrise::Comment, n.comments.first
end
+
+ def test_nested_collections_within_deeply_nested_namespace
+ n = Highrise::Deeply::Nested::Note.new(:comments => [{ :name => "1" }])
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
+ end
+
+ def test_nested_collections_in_different_levels_of_namespaces
+ n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
+ end
+
+
end