7

What's the best way to use update with a json field. I'd like my JSON field to accept new keys or update existing keys, but not overwrite the entire field. ActiveRecord does a nice job of just updating fields that changed, but I don't understand how to apply that to the sub-fields in the json record...

it 'can update settings with a plain object' do
  integration = Integration.create(
    name: 'Name',
    json_settings: {
      key1: 1,
      key2: 2
    }
  )
  integration.update(
    settings: { key2: 2 }
  )
  // json_settings is now { "key2": 3 } but I want
  // { "key1": 1, "key2": 3 } 
  expect(integration.json_settings['key1']).to eq('1') // fails
end

1 Answer 1

7

Your code should look like:

it 'can update settings with a plain object' do
  integration = Integration.create(
    name: 'Name',
    json_settings: {
      key1: 1,
      key2: 2
    }
  )
  integration.json_settings = integration.json_settings.merge { key2: 3 }
  integration.save
  expect(integration.json_settings['key1']).to eq(1)
end
Sign up to request clarification or add additional context in comments.

6 Comments

ok, that was what I was going to do, but wasn't sure if there was any rails way of updating that field with a merge by default.
yes, I'm curious if there is a way to get AR to do an atomic update too. If not when this was asked, now in AR 5.2. This answer doesn't actually answer the question.
@jrochkind The question was not related to any atomic update either.
"accept new keys or update existing keys, but not overwrite the entire field" -- "atomic update" may not be the right word for this, but that's one thing I've seen it called. This answer leads to AR code that updates the entire hash with AR's in-memory version.
Yeah the answer did it correct way. I think you are thinking too deep on this which is not needed. There is nothing about atomicity at least in this question. What OP asked, not to remove old keys/values, rather do a merge operation.
|

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.