SlideShare a Scribd company logo
1 of 41
Download to read offline
MULTI-TENANCY AND RAILS ,[object Object],RedDotRubyConf – Singapore 22-Apr-2011
Why do I care about this? ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Paul Gallagher [email_address] evendis.com personal: tardate.com twitter.com/tardate
A long time ago in a galaxy far, far away…. ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Three Thoughts for Today
A GENERAL MODEL
Multi-tenancy ,[object Object],[object Object],[object Object],[object Object]
Tenancy Models
Tenancy Models Social networks, LBS, Web 2.0 MSP/ASP, PaaS, IaaS Business, Enterprise 2.0, SaaS The same idea can manifest itself across the continuum – depending how you approach it
Tenancy Models Social networks, LBS, Web 2.0 MSP/ASP, PaaS, IaaS Business, Enterprise 2.0, SaaS Hardware/infrastructure challenge Application architecture challenge Explicit Rails support.. ..but our usage increasingly extends here
Tenancy Considerations
Key Concern: Data Partitioning
RE-USE / RE-INVENT
Four Data Partioning Techniques.. ,[object Object],[object Object],[object Object],[object Object],[object Object]
Instance Provisioning ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],The Infrastructure Engineer’s solution
RBAC Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],User Model Query scoped by permissions The “I just groked CanCan and it’s awesome” solution
RBAC Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object],class Ability include CanCan::Ability def initialize(user) … # include nil so we can handle :new can :manage, Project,  :tenant_id => [user.tenant_id, nil] … end end # then we can.. Project.accessible_by(Ability.new(current_user)) class ProjectsController < InheritedResources::Base prepend_before_filter :authenticate_user! load_and_authorize_resource # that’s all folks! end Proxy data access thru one model (user/tenant)
Model Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],users projects The Software Architect’s solution id tenant_id name … id tenant_id name …
Model Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
gem install multitenant ,[object Object],[object Object],class Account < ActiveRecord::Base has_many :users has_many :projects end class User < ActiveRecord::Base belongs_to :account belongs_to_tenant :account end class Project < ActiveRecord::Base belongs_to :account belongs_to_tenant :account end def belongs_to_tenant(association = :tenant) include DynamicDefaultScoping […] default_scope :scoped_to_tenant, lambda { return {} unless Multitenant.current_tenant where({reflection.primary_key_name => Multitenant.current_tenant.id}) } end I think I’d prefer this to return where('1=0')
gem install multitenant ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],# get a user user = User.find(1) => #<User id: 1, name: &quot;a1-u1&quot;, account_id: 1 ..> # set the current tenant Multitenant.current_tenant = user.account => #<Account id: 1, name: &quot;one” ..> # now model access is scoped Project.count => 2  # but we can bypass if we do so explicitly Project.unscoped.count => 4 # also, scoping bypassed if tenant not set Multitenant.current_tenant = nil Project.count => 4
gem install multitenant ,[object Object],class Project < ActiveRecord::Base belongs_to :account belongs_to_tenant :account validates_uniqueness_of :name, :scope => :account_id end
gem install multitenant class User < ActiveRecord::Base belongs_to :account belongs_to_tenant :account belongs_to :project end = simple_form_for [user] do |f| = f.error_messages = f.input :name = f.association :project user = User.find(1) => #<User id: 1, name: &quot;a1-u1&quot;, account_id: 1 ..> Account.find(2).projects.first.id => 3 # set the current tenant Multitenant.current_tenant = user.account Project.where(:id => 3).present? => false  # but we can still assign an inaccessible project: user.update_attributes(:project_id => 3).valid? => true # we can’t access the association user.project => nil  # but the invalid key is persisted user.project_id => 3  Since all tenant-related models are scoped, our app will display valid options to the user But what if someone sneaks in with some form-injection?
gem install multitenant ,[object Object],class User < ActiveRecord::Base belongs_to :account belongs_to_tenant :account belongs_to :project   validates_each :project_id do |record,attr,value| record.errors.add attr, &quot;is invalid&quot; unless Project.where(:id => value).present? end end
Schema Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],See Guy Naor’s definitive presentation: confreaks.net/videos/111-aac2009-writing-multi-tenant-applications-in-rails   Model AR::Connection PUBLIC TENANT1 TENANT2 TENANT n SET search_path TO TENANT2,PUBLIC; The “Now I’m using a real database let’s see what it can do” solution
Schema Partitioning User Queries Account Customer Project -- default search path: ‘$user’,PUBLIC PUBLIC
Schema Partitioning User Queries Account Customer Project PUBLIC User Account Customer Project TENANT1 SET search_path TO TENANT1, ‘$user’, PUBLIC;
Schema Partitioning User Queries Account Customer Project PUBLIC Customer Project TENANT1 SET search_path TO TENANT1, ‘$user’, PUBLIC;
Schema Partitioning ,[object Object],# default search path conn=ActiveRecord::Base.connection conn.schema_search_path => &quot;amp;quot;$useramp;quot;,public&quot;  Project.count => 4 # but if we change the search path conn.schema_search_path = ”tenant1,public&quot;  Project.count => 2  public tenant1
Schema Partitioning ,[object Object],[object Object],[object Object],[object Object],[object Object]
Warez: gem install vpd ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],gem 'vpd' class ApplicationController < ActionController::Base protect_from_forgery before_filter :set_tenant def set_tenant schema_to_use = request.subdomains.last if schema_to_use.present? # now activate the schema (and make sure # it is migrated up to date) Vpd.activate(schema_to_use,true) else # ensure we are running with the default Vpd.activate_default end end end
LESSONS LEARNT AND TTD
Think about the End-user Experience My SaaS Site Tenant 1 Tenant 2 Tenant 3 Users Users Users
Think about the End-user Experience My SaaS Site Tenant 1 Tenant 2 Tenant 3 Users Users Users ,[object Object],[object Object],[object Object],[object Object]
Disambiguation ,[object Object],[object Object],[object Object],[object Object],[object Object]
Refactoring towards multi-tenancy ,[object Object],[object Object],[object Object],[object Object],[object Object]
TAKEAWAYS
Decide early ,[object Object],[object Object],[object Object],YAGNI! Do the simplest thing possible!
‘ Productize’ ,[object Object],[object Object]
The Good News ,[object Object],[object Object],[object Object],[object Object],[object Object]
We need a ‘Rails Way’ ,[object Object],[object Object],create_table :widgets,  scope => :all  do |t| t.string :name t.timestamps end scope :only => :instance do add_column :projects, :private_attrib, :string end scope :except => :public do add_column :projects, :private_attrib2, :string  end
[object Object]

More Related Content

Similar to Multi-tenancy with Rails

Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...
Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...
Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...Vlad Mihnea
 
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfSchema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfseo18
 
Workshop - The Little Pattern That Could.pdf
Workshop - The Little Pattern That Could.pdfWorkshop - The Little Pattern That Could.pdf
Workshop - The Little Pattern That Could.pdfTobiasGoeschel
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsMarcelo Pinheiro
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on RailsMark Menard
 
Nt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language AnalysisNt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language AnalysisNicole Gomez
 
Dot Net Fundamentals
Dot Net FundamentalsDot Net Fundamentals
Dot Net FundamentalsLiquidHub
 
Onion Architecture with S#arp
Onion Architecture with S#arpOnion Architecture with S#arp
Onion Architecture with S#arpGary Pedretti
 
Madison PHP - Getting Started with Magento 2
Madison PHP - Getting Started with Magento 2Madison PHP - Getting Started with Magento 2
Madison PHP - Getting Started with Magento 2Mathew Beane
 
Monitoring as an entry point for collaboration
Monitoring as an entry point for collaborationMonitoring as an entry point for collaboration
Monitoring as an entry point for collaborationJulien Pivotto
 
Struts 2-overview2
Struts 2-overview2Struts 2-overview2
Struts 2-overview2divzi1913
 
KiranGara_JEE_7Yrs
KiranGara_JEE_7YrsKiranGara_JEE_7Yrs
KiranGara_JEE_7YrsKiran Gara
 
React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)Chiew Carol
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kuberneteskloia
 
AGADOS function & feature Chapter-02 biz logic define
AGADOS function & feature Chapter-02 biz logic defineAGADOS function & feature Chapter-02 biz logic define
AGADOS function & feature Chapter-02 biz logic defineYongkyoo Park
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionBoldRadius Solutions
 

Similar to Multi-tenancy with Rails (20)

DDD with Behat
DDD with BehatDDD with Behat
DDD with Behat
 
Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...
Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...
Ymens - Bouncing off clouds - Rapid Development for Cloud Ready Applications...
 
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfSchema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
 
Workshop - The Little Pattern That Could.pdf
Workshop - The Little Pattern That Could.pdfWorkshop - The Little Pattern That Could.pdf
Workshop - The Little Pattern That Could.pdf
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability Systems
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
 
Nt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language AnalysisNt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language Analysis
 
Dot Net Fundamentals
Dot Net FundamentalsDot Net Fundamentals
Dot Net Fundamentals
 
Onion Architecture with S#arp
Onion Architecture with S#arpOnion Architecture with S#arp
Onion Architecture with S#arp
 
.net Framework
.net Framework.net Framework
.net Framework
 
Distributed Tracing
Distributed TracingDistributed Tracing
Distributed Tracing
 
Madison PHP - Getting Started with Magento 2
Madison PHP - Getting Started with Magento 2Madison PHP - Getting Started with Magento 2
Madison PHP - Getting Started with Magento 2
 
Monitoring as an entry point for collaboration
Monitoring as an entry point for collaborationMonitoring as an entry point for collaboration
Monitoring as an entry point for collaboration
 
Struts 2-overview2
Struts 2-overview2Struts 2-overview2
Struts 2-overview2
 
KiranGara_JEE_7Yrs
KiranGara_JEE_7YrsKiranGara_JEE_7Yrs
KiranGara_JEE_7Yrs
 
React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)
 
PureMVC
PureMVCPureMVC
PureMVC
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kubernetes
 
AGADOS function & feature Chapter-02 biz logic define
AGADOS function & feature Chapter-02 biz logic defineAGADOS function & feature Chapter-02 biz logic define
AGADOS function & feature Chapter-02 biz logic define
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in Production
 

Recently uploaded

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 

Recently uploaded (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 

Multi-tenancy with Rails

  • 1.
  • 2.
  • 3.
  • 6.
  • 8. Tenancy Models Social networks, LBS, Web 2.0 MSP/ASP, PaaS, IaaS Business, Enterprise 2.0, SaaS The same idea can manifest itself across the continuum – depending how you approach it
  • 9. Tenancy Models Social networks, LBS, Web 2.0 MSP/ASP, PaaS, IaaS Business, Enterprise 2.0, SaaS Hardware/infrastructure challenge Application architecture challenge Explicit Rails support.. ..but our usage increasingly extends here
  • 11. Key Concern: Data Partitioning
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22. gem install multitenant class User < ActiveRecord::Base belongs_to :account belongs_to_tenant :account belongs_to :project end = simple_form_for [user] do |f| = f.error_messages = f.input :name = f.association :project user = User.find(1) => #<User id: 1, name: &quot;a1-u1&quot;, account_id: 1 ..> Account.find(2).projects.first.id => 3 # set the current tenant Multitenant.current_tenant = user.account Project.where(:id => 3).present? => false # but we can still assign an inaccessible project: user.update_attributes(:project_id => 3).valid? => true # we can’t access the association user.project => nil # but the invalid key is persisted user.project_id => 3 Since all tenant-related models are scoped, our app will display valid options to the user But what if someone sneaks in with some form-injection?
  • 23.
  • 24.
  • 25. Schema Partitioning User Queries Account Customer Project -- default search path: ‘$user’,PUBLIC PUBLIC
  • 26. Schema Partitioning User Queries Account Customer Project PUBLIC User Account Customer Project TENANT1 SET search_path TO TENANT1, ‘$user’, PUBLIC;
  • 27. Schema Partitioning User Queries Account Customer Project PUBLIC Customer Project TENANT1 SET search_path TO TENANT1, ‘$user’, PUBLIC;
  • 28.
  • 29.
  • 30.
  • 32. Think about the End-user Experience My SaaS Site Tenant 1 Tenant 2 Tenant 3 Users Users Users
  • 33.
  • 34.
  • 35.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.

Editor's Notes

  1. The lower in the stack you can partition More robust and secure But greater scalability challenges
  2. http://www.whitelabelapps.com/