4

我有一个使用 Apartment gem 的 rails 4.2 多租户应用程序,非常棒。

每个公司都有自己的子域。我正在使用一个自定义的“电梯”,它查看完整的请求主机以确定应该加载哪个“租户”。

当我创建一家新公司时,我有一个 after_create 挂钩来创建具有正确请求主机的新租户。

这似乎总是需要在开发和生产中重新启动服务器,否则我会收到 Tenant Not Found 错误。

它在开发中使用 sqlite,在生产中使用 postgres。

每次创建新租户时,我真的必须重新启动服务器吗?有没有一种自动化的方法来做到这一点?也许只是重新加载初始化程序就可以了,但是我不确定该怎么做/如果可能的话?

我已经搞砸了一个月,一直找不到有效的解决方案。请帮忙!

初始化程序/公寓.rb

require 'apartment/elevators/host_hash'

config.tenant_names = lambda { Company.pluck :request_host }

Rails.application.config.middleware.use 'Apartment::Elevators::HostHash', Company.full_hosts_hash

初始化程序/host_hash.rb

require 'apartment/elevators/generic'

module Apartment
    module Elevators
    class HostHash < Generic
      def initialize(app, hash = {}, processor = nil)
        super app, processor
        @hash = hash
      end

      def parse_tenant_name(request)
        if request.host.split('.').first == "www"
            nil
        else
            raise TenantNotFound,
              "Cannot find tenant for host #{request.host}" unless @hash.has_key?(request.host)
            @hash[request.host]
        end
      end
    end
    end
end 

公司模式

after_create :create_tenant


def self.full_hosts_hash
    Company.all.inject(Hash.new) do |hash, company|
      hash[company.request_host] = company.request_host
      hash
    end
end

private

    def create_tenant
        Apartment::Tenant.create(request_host)
    end

什么最终起作用

我更改了电梯配置,以摆脱公寓宝石中的 HostHash 配置,并使用了完全自定义的配置。主要基于公寓 gem github 上的一个问题:https ://github.com/influitive/apartment/issues/280

初始化程序/公寓.rb

Rails.application.config.middleware.use 'BaseSite::BaseElevator'

应用程序/中间件/base_site.rb

require 'apartment/elevators/generic'

module BaseSite
    class BaseElevator < Apartment::Elevators::Generic
        def parse_tenant_name(request)
          company = Company.find_by_request_host(request.host)

          return company.request_host unless company.nil?

          fail StandardError, "No website found at #{request.host} not found"
        end
    end
end
4

1 回答 1

1

我认为问题可能是您的host_hash.rb位于初始化程序目录中。它不应该在一个名为“中间件”的文件夹中吗?根据您在评论中引用的Apartment gem 自述文件。在那个例子中,他们使用了app/middleware/my_custom_elevator.rb。也许您的可能看起来像app/middleware/host_hash.rb

现在该文件在initializers中,所以它是从那里加载的。但是您的apartment.rb通过 . 引用它Rails.application.config.middleware.use。只是预感,但除了最初加载它之外,它可能正在一个不存在的中间件文件夹中寻找它。我会继续创建app/middleware,将文件放在那里,看看会发生什么。不确定,但您可能也需要更改require路径。

让我们知道这是否有帮助。

于 2016-04-18T02:13:00.977 回答