DEV Community

Heshie Brody
Heshie Brody

Posted on • Edited on

2 2

Update jsonb Columns Using The Rails Active Record Native Methods

While building a Rails API backend for a recent project I came across a challenge when updating jsonb columns.

You see as a pure Rail'ist (Is that a thing...?) I try to stay away from writing SQL strings in my app when I could use Active Record native methods, but since I had defined some columns as Jsonb it seemed like I would need to use SQL since all the tutorials were making use of jsonb_set SQL method as follows:

sql = 'UPDATE users SET preferences = jsonb_set(
options, \'{email_opt_in}\', \'false\', FALSE) WHERE id = 1;'

c.execute(sql)
Enter fullscreen mode Exit fullscreen mode

But as a Rail'ist I was looking for something more like user.update(params).

So...
This is what I came up with:

  1. First get the current column value which Active Record returns as a Ruby hash:
    user = session_user
    currentKeys = user.api_keys

  2. Convert post params to a hash and extract the nested values which were nested under keys:
    hashedParams = user_params.to_h[:keys]

  3. Use the Ruby hash merge method to merge my post params and current user column data:
    newKeys = currentKeys.merge(hashedParams)

  4. I could now use the Rails object update method as usual:
    user.update(api_keys: newKeys)

Here is the complete code:

    user = session_user
    currentKeys = user.api_keys
    hashedParams = user_params.to_h[:keys]
    newKeys = currentKeys.merge(hashedParams)

    if user.update(api_keys: newKeys)
        Bla, bla, bla...
Enter fullscreen mode Exit fullscreen mode

Ok, now here's the thing: I need validation if the above is acceptable as a Rail'ist(you heard it here first) so please If I'm missing anything(method, convention, irk etc.) comment below :)

Thanks For Reading!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (2)

Collapse
 
danishsatkut profile image
Danish Aziz Satkut

Your code can result in a race condition when two request execute the above code at the same time. Hence, the tutorials use the jsonb_set, which performs the modification directly at DB level.

Collapse
 
heshiebee profile image
Heshie Brody

Good point. Wrote this when I was just starting out, should definitely revise this :)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs