Rails - 具有自定义框架的多租户应用程序

时间:2011-05-02 15:20:31

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

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

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

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

我调查了一些选项,包括使用includes / extends(mixins)。问题是在生产中,方法留在对象中(可理解)。我已经尝试过使用mixology gem来解决这个问题,但它并没有像我想象的那样完全有效,而且它比我想要的更具侵入性,我也不清楚如何将它与模型联系起来(在控制器中,我刚尝试使用mixin / unmix via过滤器之前/之后。)

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

2 个答案:

答案 0 :(得分:0)

如果您正在谈论在请求之间动态切换数据库,那么我认为您正处于一个受伤的世界,至少在使用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列标记所有网站的关联记录,则可以轻松转置所有这些记录到新数据库。

答案 1 :(得分:0)

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

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