编写一个多租户Rails 3应用程序,以便在Heroku上进行部署

Ste*_*uey 13 gem model ruby-on-rails heroku multi-tenant

我正在构建一个用于在Heroku上部署的Rails 3应用程序,我想知道是否有关于如何在我的模型中处理多租户的任何建议.半年前,有一个相关的问题(#3776593)发布在这里,但没有得到很多答案.我还看过Guy Naor关于使用Rails编写多租户应用程序的演讲,但似乎3个提议的解决方案中有2个不适用于Heroku.我将链接到这些,但新的Stackoverflow用户限于2个超链接.

我还遇到了以下工具:

只是想知道你是否有多租户宝石或简单轨道多租户宝石的经验.似乎最直接的解决方案就是简单地将belongs_to放在我需要在账户下的所有模型上,但我真的很想知道你在现实世界中使用了什么!

Mik*_*ll' 6

这些方法的范围从"无共享"(通常意味着每个租户一个数据库)到"共享所有内容",这通常意味着每个表都包含来自许多租户的行.频谱(下图)可以通过隔离程度,成本(每个租户的成本)以及灾难恢复的容易程度进行细分.

  • 每个租户一个数据库; 成本最高,隔离度最高,恢复最简单.
  • 每个租户一个架构; 其他两个之间的成本,良好的隔离,相当容易的恢复,但恢复通常会降低其他租户的性能.
  • 在租户之间共享表格; 最低成本,最低隔离(共享表),难以进行灾难恢复(恢复通常意味着为每个表恢复一些行).恢复通常会使其他租户"大量"降低性能.

所有这些在某种程度上都是特定于平台的.当dbms禁止查询访问多个数据库时,"每个租户一个数据库"具有最高的隔离.但是某些平台允许跨多个数据库进行查询.

MSDN有一篇不错的文章可以达到最高点:多租户数据架构.

但如果你只限于Heroku,你必须选择Heroku支持的选项.我不知道这些选项可能是什么,但我知道你最好不要在开发中使用SQLite.Heroku部署将在PostgreSQL上运行; 你需要针对PostgreSQL进行开发.


小智 6

作为多租户宝石的作者,我显然有偏见,但我真的相信这是一个很好的解决方案!gem的目标是简化这种常见的应用程序需求,并使其实现起来很简单.

"旧学校"替代方案是使用rails对象链接来确保所有查询都通过关联的父级完成.这种方法的问题在于您的租户对象成为has_many关联的倾倒场.

class Tenant
  has_many :users
end
# query for users in the current tenant
current_tenant.users.find params[:id]
Run Code Online (Sandbox Code Playgroud)

多租户gem通过确保生成的所有查询自动识别当前租户来解决此问题. 这也保证了新的记录被创建并自动分配给目前的租户,所以你不需要添加任何特殊before_save回调.

例如:

Multitenant.with_tenant current_tenant do
  # queries within this block are automatically
  # scoped to the current tenant
  User.all

  # records created within this block are
  # automatically assigned to the current tenant
  User.create :name => 'Bob'
end
Run Code Online (Sandbox Code Playgroud)

  • 嘿ryan,你为什么不点击default_scope而不是使用Multitentant.with_tenant方式? (3认同)