2

I got my JSON posting to work with nested attributes. I can not post JSON records with the children models and it posts fine.

However, when I update a record I search for a field called "tracking_id" because the uploading program doesn't know the rails id for the model. Its a one way upload and remains agnostic to it. Using this field I can find the correct record and post an update. However the children to it get inserted instead of updated.

Is there a way i can tell it to find children based by a field I define , not just "id" since the client application will not know what that is?

Example:

#in Event Model
def self.batch_create(post_content, keymaster)
     #keymaster is the user so we can add events to the right place

  # begin exception handling
  begin
    # begin a transaction on the event model
    Event.transaction do
      # for each event record in the passed json
      JSON.parse(post_content).each do |event_hash|
        # create a new event
        # if hash has tracking_id use that
        if event_hash["tracking_id"].present?  
            event = keymaster.events.where(tracking_id: event_hash["tracking_id"]).first_or_initialize
        else
           event = keymaster.events.new
        end

        if event
          # update the existing event record
          event.update!(event_hash)
        end # event.count
      end # json.parse
    end # transaction
  rescue Exception => e
    Rails.logger.info("Did not create batch events")
    Rails.logger.info("caught exception #{e}! ohnoes!")
    # Rails.logger.info(post_content)    
  end  # exception handling
end  # batch_create

What I'd like is the same function for the children of the Event record. so that if they are already on the event it will update them not just insert new rows.

2
  • What param field(s) would you define for the controller to find child models? Can you provide some example code, preferably from your params/controller? Commented Apr 25, 2016 at 18:34
  • added more information Commented Apr 25, 2016 at 18:47

1 Answer 1

1

One possibility is to loop through the nested params and inject the id field which Rails uses to check for an existing nested_attribute:

Not sure exactly how your params are constructed, but here's the pseudocode:

For each event hash in `events_attributes` nested attributes:
  Find event by whatever attributes you've defined in your hash
  Inject `id` of found event into the attributes hash

Now that you have an id field in your nested, Rails will update the existing record (i.e. upsert), rather than creating a new record.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.