associate_jsonb
PostgreSQL JSONB extensions including:
- Basic ActiveRecord Associations using PostgreSQL JSONB columns, with built-in accessors and column indexes
- Thread-Safe JSONB updates (well, as safe as they can be) using a custom nested version of
jsonb_set(jsonb_nested_set)
Requirements:
- PostgreSQL (>= 12)
- Rails 6.0.3.2
Usage
Jsonb Associations
jsonb_set based hash updates
When enabled, only keys present in the updated hash and with values changed in memory will be updated.
To completely delete a key, value pair from an enabled attribute, set the key's value to nil.
e.g.
# given: instance#data == { "key_1"=>1,
# "key_2"=>2,
# "key_3"=> { "key_4"=>7,
# "key_5"=>8,
# "key_6"=>9 } }
instance.update({ key_1: "asdf", a: 1, key_2: nil, key_3: { key_5: nil }})
# instance#data => { "key_1"=>"asdf",
# "a"=>"asdf",
# "key_3"=> { "key_4"=>7,
# "key_6"=>9 } }
enabling/adding attribute types
first, create the sql function
rails g migration add_jsonb_nested_set_function
class CreateState < ActiveRecord::Migration[6.0]
def up
add_jsonb_nested_set_function
end
end
then in an initializer, enable key based updates:
# config/initializers/associate_jsonb.rb
AssociateJsonb.enable_jsonb_set
Key based updates rely on inheritance for allowed attribute types. Any attributes that respond true to attr_type.is_a?(GivenClass) for any enabled type classes will use jsonb_nested_set
To add classes to the enabled list, pass them as arguments to AssociateJsonb.add_hash_type(*klasses). Any arguments passed to AssociateJsonb.enable_jsonb_set are forwarded to AssociateJsonb.add_hash_type
By default, calling AssociateJsonb.enable_jsonb_set(*klasses) without arguments, and no classes previously added, adds ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb to the allowed classes list
disabling/removing attribute types
by default jsonb_nested_set updates are disabled.
if you've enabled them and need to disable, use: AssociateJsonb.disable_jsonb_set
To remove a class from the allowed list while leaving nested set updates enabled, use AssociateJsonb.remove_hash_type(*klasses).
Any arguments passed to AssociateJsonb.disable_jsonb_set are forwarded to AssociateJsonb.remove_hash_type
Automatically delete nil value hash keys
When jsonb_set updates are disabled, jsonb columns are replaced with the current document (i.e. default rails behavior)
You are also given the option to automatically clear nil/null values from the hash automatically
in an initializer, enable stripping nil values:
# config/initializers/associate_jsonb.rb
AssociateJsonb.jsonb_delete_nil = true
Rules for classes to with this applies are the same as for jsonb_nested_set; add and remove classes through AssociateJsonb.(add|remove)_hash_type(*klasses)
License
The gem is available as open source under the terms of the MIT License.