Use PostgreSQL JSONB fields to store association information of your models.
- PostgreSQL (>= 9.6)
One-to-one and One-to-many associations
You can store all foreign keys of your model in one JSONB column, without having to create multiple columns:
class Profile < ActiveRecord::Base # Setting additional :store option on :belongs_to association # enables saving of foreign ids in :extra JSONB column belongs_to :user, store: :extra end class SocialProfile < ActiveRecord::Base belongs_to :user, store: :extra end class User < ActiveRecord::Base # Parent model association needs to specify :foreign_store # for associations with JSONB storage has_one :profile, foreign_store: :extra has_many :social_profiles, foreign_store: :extra end
Foreign keys for association on one model have to be unique, even if they use different store column.
You can also use
add_references in your migration to add JSONB column and index for it (if
index: true option is set):
add_reference :profiles, :users, store: :extra, index: true
You can also use JSONB columns on 2 sides of a HABTM association. This way you won't have to create a join table.
class Label < ActiveRecord::Base # extra['user_ids'] will store associated user ids has_and_belongs_to_many :users, store: :extra end class User < ActiveRecord::Base # extra['label_ids'] will store associated label ids has_and_belongs_to_many :labels, store: :extra end
Compared to regular associations, fetching models associated via JSONB column has no drops in performance.
Getting the count of connected records is ~35% faster with associations via JSONB (tested on associations with up to 10 000 connections).
Adding new connections is slightly faster with JSONB, for scopes up to 500 records connected to another record (total count of records in the table does not matter that much. If you have more then ~500 records connected to one record on average, and you want to add new records to the scope, JSONB associations will be slower then traditional:
On the other hand, unassociating models from a big amount of associated models if faster with JSONB HABTM as the associations count grows:
Add this line to your application's Gemfile:
And then execute:
$ bundle install
To setup development environment, just run:
To run specs:
$ bundle exec rspec
To run benchmarks (that will take a while):
$ bundle exec rake benchmarks:habtm
The gem is available as open source under the terms of the MIT License.