diff --git a/lib/grape-active_model_serializers/formatter.rb b/lib/grape-active_model_serializers/formatter.rb index 2346b61..e026f1e 100644 --- a/lib/grape-active_model_serializers/formatter.rb +++ b/lib/grape-active_model_serializers/formatter.rb @@ -18,7 +18,7 @@ module Grape if resource.respond_to?(:to_ary) && !resource.empty? # ensure we have an root to fallback on - endpoint.controller_name = resource.first.class.name.underscore.pluralize + endpoint.controller_name = default_root(endpoint) end ::ActiveModel::Serializer.build_json(endpoint, resource, options) end @@ -26,6 +26,18 @@ module Grape def build_options_from_endpoint(endpoint) endpoint.namespace_options.merge(endpoint.route_options) end + + # array root is the innermost namespace name ('space') if there is one, + # otherwise the route name (e.g. get 'name') + def default_root(endpoint) + innermost_scope = endpoint.settings.peek + + if innermost_scope[:namespace] + innermost_scope[:namespace].space + else + endpoint.options[:path][0].split('/')[-1] + end + end end end end diff --git a/spec/grape_ams_spec.rb b/spec/grape_ams_spec.rb index ea4b19c..cefd83e 100644 --- a/spec/grape_ams_spec.rb +++ b/spec/grape_ams_spec.rb @@ -45,12 +45,12 @@ describe Grape::ActiveModelSerializers do end it "serializes arrays of objects" do - app.get("/home") do + app.get("/users") do user = User.new({first_name: 'JR', last_name: 'HE', email: 'contact@jrhe.co.uk'}) [user, user] end - get "/home" + get "/users" last_response.body.should == "{\"users\":[{\"first_name\":\"JR\",\"last_name\":\"HE\"},{\"first_name\":\"JR\",\"last_name\":\"HE\"}]}" end @@ -65,12 +65,12 @@ describe Grape::ActiveModelSerializers do end it "generates the proper 'root' node for serialized arrays" do - app.get("/home") do + app.get("/blog_posts") do blog_post = BlogPost.new({title: 'Grape AM::S Rocks!', body: 'Really, it does.'}) [blog_post, blog_post] end - get "/home" + get "/blog_posts" last_response.body.should == "{\"blog_posts\":[{\"title\":\"Grape AM::S Rocks!\",\"body\":\"Really, it does.\"},{\"title\":\"Grape AM::S Rocks!\",\"body\":\"Really, it does.\"}]}" end end @@ -86,15 +86,30 @@ describe Grape::ActiveModelSerializers do last_response.body.should == "{\"user\":{\"first_name\":\"Jeff\",\"last_name\":null}}" end - it 'uses the name of the closest scope (namespace/route) for the root' do - app.namespace :admin, :serializer => UserSerializer do - get('/jeff') do - User.new(first_name: 'Jeff') + context 'route is in a namespace' do + it 'uses the name of the closest namespace for the root' do + app.namespace :admin do + get('/jeff') do + user = User.new(first_name: 'Jeff') + [user, user] + end end - end - get "/admin/jeff" - last_response.body.should == "{\"admin\":{\"first_name\":\"Jeff\",\"last_name\":null}}" + get "/admin/jeff" + last_response.body.should == "{\"admin\":[{\"first_name\":\"Jeff\",\"last_name\":null},{\"first_name\":\"Jeff\",\"last_name\":null}]}" + end + end + + context 'route is not in a namespace' do + it 'uses the of the route for the root' do + app.get('/people') do + user = User.new(first_name: 'Jeff') + [user, user] + end + + get "/people" + last_response.body.should == "{\"people\":[{\"first_name\":\"Jeff\",\"last_name\":null},{\"first_name\":\"Jeff\",\"last_name\":null}]}" + end end end