Drew H
Drew H

Reputation: 4739

Saving nested JSON object to database

Lets say I have a model.

Passengers belongs to Flights. Flights belongs to Trips

class Trip < ActiveRecord::Base    
    has_many :flights, :dependent => :destroy, :order => "order_num ASC"    
end


class Flight < ActiveRecord::Base
    belongs_to :trip, touch: true
    has_many :passengers, :dependent => :destroy
end

class Passenger < ActiveRecord::Base
    belongs_to :flight, touch: true
end

And I'm getting this sent back to the rails app. (when the user calls save).

*The top level is the trip

{    
    name: 'Hello Trip',
    date: '2013-08-12',
    flights: [
        {
            id: 1
            depart_airport: 'RDU',
            arrive_airport: 'RDU',
            passengers: [
                {
                    user_id: 1,
                    request: true
                }
            ]
        },

        {

            depart_airport: 'RDU',
            arrive_airport: 'RDU',
            passengers: [
                {
                    user_id: 1,
                    request: true
                },
                {
                    user_id: 2
                    request:true
                }
            ]
        }

    ]
}

Right now I'm getting the saved json in and manually looping through the flights to see if there is an id. If there is i'm updating it. If not I'm creating a new one. Then adding the passengers.

I'm wondering if there is an automatic format that Rails takes that can do all the saving for me. I know when you submit a nested form it creates a similar pattern, and adds a _destroy property and the id is a timestamp if it's just created. Would the JSON saving be similar to that?

Thanks for any help!

Upvotes: 1

Views: 1095

Answers (1)

Jacob Brown
Jacob Brown

Reputation: 7561

Yes, you should be able to use accepts_nested_attributes_for here.

You'll need to enable accepts_nested_attributes_for on your models, e.g.,

class Trip < ActiveRecord::Base    
  has_many :flights, :dependent => :destroy, :order => "order_num ASC" 
  accepts_nested_attributes_for :flights, :allow_destroy => true
  attr_accessible :flights_attributes
end

You'll also need to ensure that your JSON response uses keys that Rails will recognize. You can either modify the JSON response or do something like:

response = JSON.parse(json_string)
response[:flights_attributes] = response.delete(:flights)
# ...

Then you can just do

Trip.create(response)

You'll want to ensure that everything is created/updated as expected. For more on accepts_nested_attributes_for, see the documentation: http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for.

I think accepts_nested_attributes_for is convenient, but note that there are some that think it should be deprecated (e.g., here: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/, see here for a response: https://stackoverflow.com/a/17639029/1614607).

Upvotes: 1

Related Questions