【问题标题】:Rails - Multi tenant application with customization frameworkRails - 具有自定义框架的多租户应用程序
【发布时间】:2011-08-17 01:37:12
【问题描述】:

我正在组织一个带有单个代码库/应用程序的多租户应用程序,它使用子域来检测租户,然后在 postgres 上运行 SET SCHEMA 来做有趣的事情。

我的问题是某些客户需要对主代码库进行不同级别的自定义。不是很多,但肯定足以让我不想通过添加一堆 if 语句来开始破解主要模型和控制器。

使用视图加载路径覆盖视图很容易......但我的问题是:我如何提供一个好的框架来覆盖或添加基本控制器、模型和助手的功能,以便根据需要为每个租户调整内容?理想情况下,它应该非常无缝且不会侵入主代码,并且应该为组织自定义代码提供一个体面的机制。

我研究了一些选项,包括使用包含/扩展(混合)。问题是在生产中,方法保留在对象中(可以理解)。我已经尝试过混合学 gem 来解决这个问题,但它并没有完全按照我的预期工作,而且它比我想要的更具侵入性,我也不清楚如何将它与模型相关联(在控制器中,我刚刚尝试通过之前/之后过滤器进行混合/取消混合)。

如果有人对如何最好地处理/解决此问题有任何想法,我将非常感谢您的反馈。 FWIW 这是 Rails3

【问题讨论】:

标签: ruby-on-rails ruby model-view-controller multi-tenant


【解决方案1】:

如果您正在谈论在请求之间动态切换数据库,那么我认为您将陷入困境,至少在使用 ActiveRecord 时是如此。这将严重扰乱缓存系统,因为它会根据 ID 而不是 ID + Schema 记住事物,这可能会导致交叉污染。

一般来说,从架构的角度来看,最好在内部对数据库进行分区,并对每条记录进行相应的范围划分。例如:

class Site < ActiveRecord::Base
  # Represents a site or installation of the application
end

class User < ActiveRecord::Base
  belongs_to :site
end

将所有内容链接到主要的 Site 记录,或任何最能描述您用于分区的方法的术语。保持一致的范围比切换架构要容易得多。

如果出于扩展的原因,您希望将来拆分数据库,如果您小心地使用一致的site_id 列标记站点的所有关联记录,则可以轻松转置所有这些记录到一个新的数据库。

【讨论】:

  • 塔德曼,感谢您的回复。数据库不是真正的问题,交叉污染也不是问题。我不会即时切换数据库,我将使用 postgres 的模式功能并选择带有环绕过滤器的模式,这应该没问题。而且由于我不是多线程,它应该很好并且没有交叉污染。实际上,您可以在 2009 年的acts_as_conference 上看到 Morph Labs 的 Guy Naor 的证明:bestechvideos.com/2009/03/26/…。我的问题与自定义功能更相关。
  • 出于各种原因,包括但不限于安全性,在共享表中限定 site_id 不是一种选择。我也认为这比 postgres 的模式更容易发生交叉污染的“错误”。
  • 最可靠的方法是为每个实例使用不同的database.yml 文件进行单独的部署,如果通过像Passenger 这样的负载平衡前端进行管理,它并没有听起来那么糟糕。也许在这个意义上我更老派。我会看看那个视频。
  • 问题不在于数据。此外,不希望通过不同的数据库分离数据。这将需要我在客户端级别管理实例,这将是一个正确扩展的 PITA(一些客户端很热,一些不是,等等)。关于数据,在我的情况下最有效的方法是 pg 模式。正如我所指出的,我的问题专门针对每个客户的定制。这意味着对控制器、模型和视图的更改(在租户级别覆盖默认 MVC,而不创建完全独立的应用程序)
  • 那么我想我和你一样好奇这个问题的答案是什么。
【解决方案2】:

挂钩 + 插件设置能满足您的需求吗?即:将附加功能构建到另一个模型中,在您需要修改的任何操作上检查钩子表以查看用户是否需要任何额外的操作,钩子表还指定要采取的操作,因此您可以轻松地为不同的用户设置不同的配置。

如果您找到了更好的答案,请更新。

【讨论】:

  • 实际上,这与我最终采用的方法非常相似。代码需要改进,但它似乎工作。基本上我为数据库中的类定义新方法(包括方法的代码),或重新定义数据库中的方法。在运行时,它会检查给定上下文是否存在修改过的动作或新动作,并运行 eval 代码。在重新定义动作的情况下,我为旧动作创建一个别名,然后在请求完成时取消别名——这在单线程环境中应该可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 2013-03-24
  • 2012-07-18
  • 2021-08-08
  • 2014-02-10
  • 2018-08-29
  • 1970-01-01
相关资源
最近更新 更多