How to work with JSONB column in pure Ruby on Rails
JSONB columns are incredibly versatile and efficient and are an excellent way to add flexibility to your application database. This guide will explore how to use JSONB columns in your Ruby on Rails application with read, write, setting defaults and validation.
What is a JSONB Column?
Before we dive into the practicalities, let's explore what a JSONB column is. PostgreSQL introduced the JSONB datatype in version 9.4 as an improvement over the previously implemented JSON datatype. It provides the powerful ability to store structured, complex data within a single database column.
Using JSONB in Ruby on Rails
To interact with JSONB columns in Ruby on Rails, we use the built-in store_accessor
. It creates methods to directly access stored data, just like you'd do with any other attribute. Consider this sample code:
module SettingKeysRequirable
attr_reader :required_settings_keys
def set_required_settings_keys(keys)
@required_settings_keys = keys
store_accessor :settings, @required_settings_keys
validates_presence_of @required_settings_keys
end
end
In this setup, we define the set_required_settings_keys
function, which not only marks certain keys on the settings (a JSONB column in our case) as required
, but also makes sure those keys are present using Rails' validates_presence_of
function. The behavior is stored in an instance variable and read via attr_reader
.
With the SettingKeysRequirable
module in place, it's time to leverage its utility in our user
model.
class User < ApplicationRecord
extend SettingKeysRequirable
set_required_settings_keys %w(url login_url my_default_key) # we have 'settings' column as a jsonb in User table in this example
def set_default_settings!(current_domain: 'www.abc.pl')
self.settings = {
my_extra_stuff: 'my_extra_value',
my_default_key: 'my_default_value',
login_url: "#{current_domain}/login",
}
end
end
In the User
model, we've defined a few keys (url
, login_url
, and my_default_key
) as required settings. This clarification means they have to be present in the settings of each User
record. Note that the settings column itself must be of type JSONB.
Working with records
Next, let's use these newly defined methods to interact with our user
records:
id = User.new
id.login_url
# => nil
id.set_default_settings!
id.login_url
# => "www.abc.pl/login" # loaded default settings
id.url
# => nil
id.valid?
# => false
id.errors.full_messages
# => ["Url can't be blank"]
id.url = 'www.blabla.pl' # access directly to attribute from JSONB settings column
id.valid?
# => true
id.save!
# => true
This example shows that we can read from and write to our JSONB settings
column just like any other attribute.
Summary
Working with JSONB in Ruby on Rails is an efficient and flexible way to store and manipulate structured data. It allows us to define and validate keys directly within a JSONB hash, simplifying and streamlining our coding practices. Dive in and give it a try!
Happy Coding!