mysql - Rails Web API 中的单模式 Multi-Tenancy

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

我有一个客户端应用程序——Angular JS 前端和一个带有 MySQL 数据库的 Rails API 后端。我正在尝试将应用程序转换为单一架构 Multi-Tenancy 应用程序。我读了很多书,并且:

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

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

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

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

提前致谢!

最佳答案

不使用 default_scope 是个好主意 - 它的行为就像一个黑盒子,可能会破坏整个线路,尤其是当你对偏执删除进行任何操作时。

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

在您的 Controller 中,您可以检测当前请求的租户(使用子域或 token )并设置 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

关于mysql - Rails Web API 中的单模式 Multi-Tenancy ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40777028/

相关文章:

ruby - 如何将方法和对象直接传递到 block 中?

mysql - 2 表查询只显示某些行

mysql - 如果字段存在,Django 过滤查询集

java - 如何随机选择遍历列的数据并在 Mysql DB 中形成一行?

javascript - RAILS 不渲染 js.erb

ruby-on-rails - 无法推送到 github,ssh : Could not resolve hostname

ruby - 无法在您的 Gemfile 中列出的任何 gem 源中找到 gem

mysql - 根据mysql中时区的当前时间排序

ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge

ruby 线程输出