All Projects → citusdata → Activerecord Multi Tenant

citusdata / Activerecord Multi Tenant

Licence: mit
Rails/ActiveRecord support for distributed multi-tenant databases like Postgres+Citus

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to Activerecord Multi Tenant

Order query
Find next / previous Active Record(s) in one query
Stars: ✭ 472 (-10.27%)
Mutual labels:  activerecord, rails
Isolator
Detect non-atomic interactions within DB transactions
Stars: ✭ 362 (-31.18%)
Mutual labels:  activerecord, rails
Html5 validators
A gem/plugin for Rails 3, Rails 4, Rails 5, and Rails 6 that enables client-side validation using ActiveModel + HTML5 Form Validation
Stars: ✭ 302 (-42.59%)
Mutual labels:  activerecord, rails
Ar lazy preload
Lazy loading associations for the ActiveRecord models
Stars: ✭ 281 (-46.58%)
Mutual labels:  activerecord, rails
Store model
Work with JSON-backed attributes as ActiveRecord-ish models
Stars: ✭ 410 (-22.05%)
Mutual labels:  activerecord, rails
Pg party
ActiveRecord PostgreSQL Partitioning
Stars: ✭ 294 (-44.11%)
Mutual labels:  activerecord, rails
Attribute normalizer
Adds the ability to normalize attributes cleanly with code blocks and predefined normalizers
Stars: ✭ 473 (-10.08%)
Mutual labels:  activerecord, rails
Clowne
A flexible gem for cloning models
Stars: ✭ 260 (-50.57%)
Mutual labels:  activerecord, rails
Deep pluck
Allow you to pluck attributes from nested associations without loading a bunch of records.
Stars: ✭ 385 (-26.81%)
Mutual labels:  activerecord, rails
Second level cache
Write Through and Read Through caching library inspired by CacheMoney and cache_fu, support ActiveRecord 4, 5 and 6.
Stars: ✭ 380 (-27.76%)
Mutual labels:  activerecord, rails
Pluck to hash
Extend ActiveRecord pluck to return array of hashes
Stars: ✭ 275 (-47.72%)
Mutual labels:  activerecord, rails
Strip attributes
🔪 An ActiveModel extension that automatically strips all attributes of leading and trailing whitespace before validation. If the attribute is blank, it strips the value to nil.
Stars: ✭ 441 (-16.16%)
Mutual labels:  activerecord, rails
Elasticsearch Rails
Elasticsearch integrations for ActiveModel/Record and Ruby on Rails
Stars: ✭ 2,896 (+450.57%)
Mutual labels:  activerecord, rails
Zero downtime migrations
Zero downtime migrations with ActiveRecord 3+ and PostgreSQL
Stars: ✭ 513 (-2.47%)
Mutual labels:  activerecord, rails
Public activity
Easy activity tracking for models - similar to Github's Public Activity
Stars: ✭ 2,822 (+436.5%)
Mutual labels:  activerecord, rails
Algoliasearch Rails
AlgoliaSearch integration to your favorite ORM
Stars: ✭ 352 (-33.08%)
Mutual labels:  activerecord, rails
Activerecord Postgres enum
Integrate PostgreSQL's enum data type into ActiveRecord's schema and migrations.
Stars: ✭ 227 (-56.84%)
Mutual labels:  activerecord, rails
Scenic
Scenic is maintained by Derek Prior, Caleb Hearth, and you, our contributors.
Stars: ✭ 2,856 (+442.97%)
Mutual labels:  activerecord, rails
Annotate models
Annotate Rails classes with schema and routes info
Stars: ✭ 3,849 (+631.75%)
Mutual labels:  activerecord, rails
Rails Pg Extras
Rails PostgreSQL database performance insights. Locks, index usage, buffer cache hit ratios, vacuum stats and more.
Stars: ✭ 432 (-17.87%)
Mutual labels:  activerecord, rails

activerecord-multi-tenant

Introduction Post: https://www.citusdata.com/blog/2017/01/05/easily-scale-out-multi-tenant-apps/

ActiveRecord/Rails integration for multi-tenant databases, in particular the open-source Citus extension for PostgreSQL.

Enables easy scale-out by adding the tenant context to your queries, enabling the database (e.g. Citus) to efficiently route queries to the right database node.

Installation

Add the following to your Gemfile:

gem 'activerecord-multi-tenant'

Supported Rails versions

All Ruby on Rails versions starting with 4.2 or newer (up to 6.0) are supported.

This gem only supports ActiveRecord (the Rails default ORM), and not alternative ORMs like Sequel.

Usage

It is required that you add multi_tenant definitions to your model in order to have full support for Citus, in particular when updating records.

In the example of an analytics application, sharding on customer_id, annotate your models like this:

class PageView < ActiveRecord::Base
  multi_tenant :customer
  belongs_to :site

  # ...
end

class Site < ActiveRecord::Base
  multi_tenant :customer
  has_many :page_views

  # ...
end

and then wrap all code that runs queries/modifications in blocks like this:

customer = Customer.find(session[:current_customer_id])
# ...
MultiTenant.with(customer) do
  site = Site.find(params[:site_id])
  site.update! last_accessed_at: Time.now
  site.page_views.count
end

Inside controllers you can use a before_action together with set_current_tenant, to set the tenant for the current request:

class ApplicationController < ActionController::Base
  set_current_tenant_through_filter # Required to opt into this behavior
  before_action :set_customer_as_tenant

  def set_customer_as_tenant
    customer = Customer.find(session[:current_customer_id])
    set_current_tenant(customer)
  end
end

Rolling out activerecord-multi-tenant for your application (write-only mode)

The library relies on tenant_id to be present and NOT NULL for all rows. However, its often useful to have the library set the tenant_id for new records, and then backfilling tenant_id for existing records as a background task.

To support this, there is a write-only mode, in which tenant_id is not included in queries, but only set for new records. Include the following in an initializer to enable it:

MultiTenant.enable_write_only_mode

Once you are ready to enforce tenancy, make your tenant_id column NOT NULL and simply remove that line.

Frequently Asked Questions

  • What if I have a table that doesn't relate to my tenant? (e.g. templates that are the same in every account)

    We recommend not using activerecord-multi-tenant on these tables. In case only some records in a table are not associated to a tenant (i.e. your templates are in the same table as actual objects), we recommend setting the tenant_id to 0, and then using MultiTenant.with(0) to access these objects.

  • What if my tenant model is not defined in my application?

    The tenant model does not have to be defined. Use the gem as if the model was present. MultiTenant.with accepts either a tenant id or model instance.

Credits

This gem was initially based on acts_as_tenant, and still shares some code. We thank the authors for their efforts.

License

Copyright (c) 2018, Citus Data Inc.
Licensed under the MIT license, see LICENSE file for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].