• Stars
    star
    717
  • Rank 63,167 (Top 2 %)
  • Language
    Ruby
  • License
    MIT License
  • Created about 8 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

activerecord-multi-tenant

Build Status codecov Gems Version Gem Download Count Documentation Status

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 6.0 or newer (up to 7.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.

More Repositories

1

citus

Distributed PostgreSQL as an extension
C
10,512
star
2

pg_cron

Run periodic jobs in PostgreSQL
C
2,846
star
3

cstore_fdw

Columnar storage extension for Postgres built as a foreign data wrapper. Check out https://github.com/citusdata/citus for a modernized columnar storage implementation built as a table access method.
C
1,758
star
4

postgresql-hll

PostgreSQL extension adding HyperLogLog data structures as a native data type
C
1,116
star
5

pg_shard

ATTENTION: pg_shard is superseded by Citus, its more powerful replacement
C
1,058
star
6

pg_auto_failover

Postgres extension and service for automated failover and high-availability
C
852
star
7

django-multitenant

Python/Django support for distributed multi-tenant databases like Postgres+Citus
Python
722
star
8

postgres_vectorization_test

Vectorized executor to speed up PostgreSQL
C
331
star
9

docker

🚢 Docker images and configuration for Citus
Dockerfile
241
star
10

postgresql-topn

TopN is an open source PostgreSQL extension that returns the top values in a database according to some criteria
C
238
star
11

mongo_fdw

DEPRECATED, moved to
C
154
star
12

podyn

DynamoDB to PostgreSQL & Citus continuous replication tool
Java
85
star
13

citus-example-ad-analytics

Reference App for Ad Analytics, using Ruby on Rails.
CSS
75
star
14

citus_docs

Documentation for Citus. Distributed PostgreSQL as an extension.
CSS
58
star
15

pgconfsv-tutorial

Files for the PGConf SV tutorial on real-time analytics
Python
54
star
16

citus-benchmark

Tools for running benchmarks against Citus
Python
38
star
17

postgres-analytics-tutorial

Exercises for the Architecting Real-Time Analytics for your Customers tutorial
PLpgSQL
28
star
18

membership-manager

🚢 Docker image for managing Citus membership via docker-py
Python
21
star
19

packaging

Packaging scripts for Citus
Dockerfile
19
star
20

test-automation

Tools for making our tests easier to run
C
14
star
21

tools

Tools and config used in Citus Data projects
Python
14
star
22

pgconfus-tutorial-multi-tenant

Files for the tutorial on Citus & Multi-Tenant Models @ PGConf US 2017
Ruby
10
star
23

pg_octopus

A health checker for PostgreSQL
C
9
star
24

python-citus-rebalancer

A python command line tool to recommend shard moves to customers with unbalanced clusters
Python
9
star
25

pgmasq

Transparently forward transactions from a hot standby to a primary in PostgreSQL (failed experiment)
C
8
star
26

citus-django-example-ad-analytics

Reference App for Ad Analytics, using Django
CSS
8
star
27

pg_intpair

C
7
star
28

the-process

Trust it.
Dockerfile
6
star
29

interactive-tutorials

Shell
5
star
30

realtime-dashboards-resources

Some useful scripts
PLpgSQL
5
star
31

pg_shard-old

Repo used for pg_shard development before release.
C
4
star
32

PathToCitusCon

This repo stores show notes for our PathToCitusCon series of events on Discord
3
star
33

citus-example-microservices

Python
3
star
34

workerlist-gen

🚢 Docker image for generating Citus workerlist file using docker-gen
Shell
3
star
35

real-time-analytics-Hands-On-Lab-Hyperscale-Citus

2
star
36

Nationwide-Hands-On-Session

1
star