ruby-on-railsjsonnested-attributesaccepts-nested-attributes

Rails Nested Attributes JSON Formatting


I'm trying to override the 'as_json' method to include nested attributes for an object, but I'm having trouble properly nesting the JSON.

Currently, I have this in Rails for my 'as_json' method.

// User.rb

def as_json(options = {})
  json = {:id => id, :name => name,
    :settings_attributes => settings.select(:id,:name), 
    :setting_options_attributes => setting_options.select(:id, :amount)}
  json
end

However, setting_options_attributes should be nested under settings_attributes and I can't find the proper syntax do achieve this.


Solution

  • Assuming settings and settings_options are already hashes, you should be able to do this:

    // User.rb
    def as_json(options = {})
      {
        id: id, 
        name: name,
        settings_attributes: settings.select(:id,:name).merge({
          setting_options_attributes: setting_options.select(:id, :amount)
        }, 
      }
    end
    

    If settings and settings_options are Models, then you probably need to do something like this:

    // User.rb
    def as_json(options = {})
      {
        id: id, 
        name: name,
        settings_attributes: settings.select(:id,:name).map(&:attributes), 
      }
    end
    
    // Setting.rb
    def attributes
      {
        id: id, 
        name: name,
        setting_options_attributes: setting_options.select(:id,:amount).map(&:attributes), 
      }
    end
    

    It's a little confusing in that SettingOption appears to belong_to User (as you reference it directly) yet you want to nest it within Setting, which implies that it is a "belongs_to :through" relationship, at which point I think you should make Setting responsible for the nesting.

    Lastly, if you want to develop complex JSON output, rather than override as_json, you should consider using jbuilder (which is typically bundled with rails) as it moves your JSON logic out of your model and into the view, which is arguably the more appropriate place to be constructing how you view your data. JBuilder is much better at designing complex JSON.