SlideShare a Scribd company logo
1 of 41
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
 
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel PartnersCraeg Strong
 

Similar to Multi-tenancy with Rails (20)

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
 
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners
20211202 NADOG Adapting to Covid with Serverless Craeg Strong Ariel Partners
 

Recently uploaded

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
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
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
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
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 

Recently uploaded (20)

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
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
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
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.
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 

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/