Search code examples
ruby-on-railsjsonruby-on-rails-3activeresource

Disable json root element in embedded objects on ActiveResource query


I got problem with unnecessary root element in embedded json object. Here is the cleaned sources:

User model:

class User < ActiveResource::Base
      self.format = :json
      self.element_name = "user"
      #...
end

Controller's action 'new'

def new
 @user = User.build
 @user.id = nil
end

User.build gives me next json:

{
  "id":0,
  "user_name":null,
  "credit_card":
    {"number":null}
}

Controller's action 'create'

def create
    @user = User.new(params[:user])
    @user.save
end

View '_form.html.erb'

<%= form_for(@user) do |f| %>
    <%= f.label :user_name %>
    <%= f.text_field :user_name %>

        <%= f.fields_for @user.credit_card do |cc_f| %>
            <%= cc_f.label :number %>
            <%= cc_f.text_field :number %>
        <% end %>
<% end %>

When I'm saving user app send next json:

{
 "user"=>
   {"credit_card"=>
     {"credit_card"=>
       {"number"=>"xxxxyyyyzzzzaaaa"}
     }, 
   "user_name"=>"test"
    }, 
 "api_client_key"=>"top_secret"
}

Problem is in duplication of credit_card keys. How can i solve it?


Final solution:

class User < ActiveResource::Base
      self.include_root_in_json = false
      self.format = :json
      self.element_name = "user"

      def to_json(options = {})
          {
             self.class.element_name => self.attributes
          }.to_json(options)
      end
# ...
end

thanks to Oliver Barnes


Solution

  • Try

    ActiveResource::Base.include_root_in_json = false
    

    If you need to keep the top root and just remove the associated credit card object's root, then you might need to customize the json output with #to_json, like this:

    def to_json(options = {})
      { "user"=>
          {"credit_card"=>
            {"number"=> self.credit_card.number }
           }, 
            "user_name"=> self.user_name
       }.to_json(options)
    end