【问题标题】:Single schema multi tenancy in a Rails Web APIRails Web API 中的单模式多租户
【发布时间】:2017-04-08 04:54:11
【问题描述】:

我有一个客户端应用程序 - Angular JS 前端和带有 MySQL 数据库的 Rails API 后端。我正在尝试将应用程序转换为单一模式多租户应用程序。我做了很多阅读并且:

  • 如果可能,我不想使用 gem - Apartment,它是多个模式并使用 Postgres 不符合要求,并且 act_as_tenant 似乎使用 Thread.current 来识别我不想做的租户。
  • 我已经读过 default_scope 也不应该被使用,原因有很多我不会在这里讨论。

我将请求标头中的租户令牌从前端传递到 Rails 后端,并使用租户令牌在我的 ApplicationController 中识别租户。我现在正在寻找读取和写入数据的最佳方式,以便与发出请求的租户相关联。

排除了上述选项后,我能看到的唯一选择是进入我的所有控制器方法,并在写入和读取数据的任何地方更新它们。我更愿意对我的每个模型应用某种回调,以便在写入数据时始终写入租户 ID,并且在读取数据时始终将租户 ID 用作过滤器。

鉴于我无法访问模型中的租户令牌,除了更新我的所有控制器方法之外,我不确定如何继续此操作,这将是一个艰巨且容易出错的过程。

提前致谢!

【问题讨论】:

    标签: mysql ruby-on-rails ruby schema multi-tenant


    【解决方案1】:

    不使用 default_scope 是个好主意 - 它的行为有点像黑匣子,可能会造成严重破坏,尤其是当您对偏执删除进行任何操作时。

    按照您的要求进行操作的一种方法是使用thread_mattr_accessor。您可以在 Web 请求开始时定义tenant_id 令牌,然后在 Web 请求期间通过 class 属性访问它。这会在您的租户模型上创建一个线程安全的属性访问器。

    在您的控制器中,您可以检测当前请求的租户(使用子域或令牌)并设置 Token.current_id 变量。此变量将在请求期间可用。请注意,它不会自动用于任何后台作业或其他进程,因为该变量是在当前线程中设置的。

    此方法在this RailsCast 中使用范围进行了演示,但您不必使用范围。您可以设置一个辅助方法,如current_tenant,然后显式限定所有查询,如current_tenant.posts

    # models/tenant.rb
    class Tenant < ApplicationRecord
      thread_cattr_accessor :current_id
      # ...
    end
    
    # controllers/application_controller.rb
    class ApplicationController < ActionController::Base
    
      around_action :scope_current_tenant
      private def scope_current_tenant
        Tenant.current_id = current_tenant.id
        yield
      ensure
        Tenant.current_id = nil
      end
    
      def current_tenant
        @current_tenant ||= Tenant.find_by_token! params[:token]
      end
    
      helper_method :current_tenant
    end
    

    【讨论】:

    • 我推荐 Ryan Bigg 的书,名为 Multitenancy with Rails,可从 Leanpub 获得。
    • 谢谢!不过我有几个问题:现在已经确定了当前租户 - 我如何更新我的其他模型,以便在读取数据时写入当前租户 ID 并用作过滤器? current_tenant.id 或 Tenant.current_id 是否可用于这些模型,例如 - User 模型?
    • 您可以使用 current_tenant 变量来确定所有查询的范围。例如current_tenant.users.find(params[:id])。由于您已将 current_tenant 定义为辅助方法,因此您也可以在视图中使用它。
    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 2014-10-14
    • 2013-03-24
    相关资源
    最近更新 更多