我正在使用Apartment gem来构建一个多租户应用程序(每个租户都使用不同的Postgres架构).
Rails为每个租户定义自定义CSS覆盖的最佳方法是什么?
我知道默认情况下,Apartment将在公共数据库和租户数据库上创建相同的表。而且公共数据库上的大多数表都是无用的空表。我也知道租户数据库取决于schema.rb
但是我想知道我们是否可以为公共数据库和租户数据库使用不同的架构?例如,我有5个表:SignUp,Company,User,Task和Matter。
如果我希望主数据库(公共)仅具有SignUP,COmpany和User表,而租户仅具有Task和Matter表,是否可以这样做?
基本上我想要实现的是:
但是,我的问题是我不知道如何从Generic Elevator提供的请求(Rack :: Request)对象中检索当前用户.有关如何操作的任何提示或有任何其他方式来获取当前用户没有请求?
我正在使用设计进行身份验证.
我正在将我的Rails项目转换为多租户,我正在使用Apartment.
我按照他们自述文件上的说明和他们链接到的视频
我apartment.rb看起来像这样:
require 'apartment/elevators/subdomain'
Apartment.configure do |config|
  config.excluded_models = ['Project', 'User']
  config.tenant_names = lambda { Project.pluck :subdomain }
  config.use_schemas = true
  config.persistent_schemas = %w{ public }
end
Rails.application.config.middleware.use Apartment::Elevators::Subdomain
Run Code Online (Sandbox Code Playgroud)
我的项目模型如下所示:
class Project < ApplicationRecord
  after_create :create_tenant
  private
  def create_tenant
    Apartment::Tenant.create(subdomain)
  end
end
Run Code Online (Sandbox Code Playgroud)
我可以运行db:migrate和db:setup没问题.然后它在公共模式中创建我的所有表.
但是,当我尝试创建一个新项目时,我得到了这个(来自rails c)
C:\code\vulnerability-history>rails c
Loading development environment (Rails 5.0.1)
irb(main):001:0> Project.create(name: 'foo', subdomain: 'bar')
   (0.0ms)  BEGIN
  SQL (1.0ms)  INSERT INTO "public"."projects" ("name", "subdomain") VALUES ($1, $2) RETURNING "id"  [["name", "foo"], ["subdomain", …Run Code Online (Sandbox Code Playgroud) 我已经在Apartment(1.2.0)和Devise(4.2.0)中设置了Rails 5应用程序.由于一些DDNS问题,存在约束,即应该只能访问应用程序app.myapp.com(注意子域app).myapp.com重定向到app.myapp.com.
我的用例是,每个注册到应用程序的用户(租户)都应该通过他们的子域(例如tenant.myapp.com)访问他们的特定数据.不应将用户限定为其子域.基本上应该可以从任何子域登录.重定向到租户的正确子域由ApplicationController.处理.根据Devise标准,登录页面位于app.myapp.com/users/sign_in.这就是问题的开始:
由于"电子邮件或密码不正确"错误,用户无法登录.
在开发过程中我玩了一下.从lvh.me作品中登录完美.用户已登录并重定向到其子域.尝试相同app.lvh.me会导致上述问题.
我已将会话存储设置为:
# /config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: {
  production:   '.app.myapp.com',
  staging:      '.app.myapp.com',
  development:  '.app.lvh.me'
}.fetch(Rails.env.to_sym, :all)
Run Code Online (Sandbox Code Playgroud)
我也尝试过以下方法:
Rails.application.config.session_store :cookie_store, key: '_myapp_session', domain: :all
Run Code Online (Sandbox Code Playgroud)
我需要做什么才能从任何子域登录?
测试案例将是:
用户user1访问网址app.myapp.com/users/sign_in提供其凭据,因此登录并重定向到user1.myapp.com.
奖励:user1访问网址another_user.myapp.com/users/sign_in提供他们的凭据,因此登录并重定向到user1.myapp.com.
其他相关配置:
# /config/initializers/apartment.rb
config.excluded_models = %w{ User }
config.tenant_names = lambda { …Run Code Online (Sandbox Code Playgroud) 我想在使用公寓 gem 的 Heroku 多模式 pgSQL 应用程序上使用 pg_dump,但恐怕我有太多模式无法使其工作。
我查看了它,并在以下链接中从公寓宝石的创建者那里找到了以下内容
我是此处引用的 Apartment gem 的作者。我们已经在 Heroku 上使用它一年多了,它利用了模式。
使用起来绝对没问题,我们仍然可以在每个模式有 50 多个表的应用程序中使用超过 100 个模式获得出色的性能。
@4ware 提到的文章谈到了 heroku 的 pg:backups 命令的问题。(我很确定这篇文章来自我们对他们的支持查询)
它肯定有问题,但这不是 Postgresql、模式或多租户模式的缺点,而是 heroku 工具本身的缺点。既然 Postgresql 在他们的 dbs 上有 ingres 支持,你真的不需要使用他们的内置工具。我们只是在需要时 pg_dump 并且它的工作速度与人们预期的一样快。
如何使用外部工具?有人可以详细说明一下吗?
下面的代码config/initializers/console.rb仅在我第一次执行rails consoleCLI 时才存储。退出并再次进入时,不会显示选择消息,但会加载所选的预览租户。
if defined?(Rails::Console) || $PROGRAM_NAME.include?('spring')
  tenants = Apartment.tenant_names.sort
  default = tenants.first
  puts "Available tenants: #{tenants.join(', ')}"
  print "Select tenant (#{default}): "
  tenant = gets.strip
  Apartment::Tenant.switch! tenants.include?(tenant) ? tenant : default
end
Run Code Online (Sandbox Code Playgroud)
我希望每次进入时rails console询问将加载什么租户。
谢谢!
我在尝试时遇到错误
bundle exec rails generate apartment:install
Run Code Online (Sandbox Code Playgroud)
得到这个错误,
build': undefined method new' for "Apartment::Reloader":String (NoMethodError)
看起来这是一个中间件问题。任何解决方案。
情况是这样的。我有一个使用 Apartment gem 的多租户 Rails 应用程序,我需要在其中实施 LinkedIn OmniAuth 策略。
正如您从我的路由中看到的,Devise 用户和关联的路由仅保留在子域的各个架构上。
路线示例:
好的:https://frank.example.io/users/sign_in
坏的:https://example.io/users/sign_in
路线
class SubdomainPresent
  def self.matches?(request)
    request.subdomain.present?
  end
end
class SubdomainBlank
  def self.matches?(request)
    request.subdomain.blank?
  end
end
Rails.application.routes.draw do
  constraints(SubdomainPresent) do
    ...
    devise_for :users, controllers: { 
      omniauth_callbacks: 'omniauth_callbacks'
    }
    devise_scope :user do
      get '/users/:id', to: 'users/registrations#show', as: "show_user"
    end
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)
我的具体问题是 LinkedIn 不支持通配符及其回调 URL,因此我不知道如何在 OAuth 身份验证后将用户定向到正确的域。
我有两个 Rails 应用程序base1和base2.
base1db1在该数据库中使用并拥有多个租户,其使用公寓 gem。
base2是单租户应用程序,以数据库db2为主,并且还使用来自db1.
现在的问题是,base2应用程序建立了连接,我可以在应用程序中获取公共租户中的db1数据数据。如何从应用程序的不同模式中获取数据?db1base2db1base2
apartment-gem ×10
ruby-on-rails ×10
multi-tenant ×4
devise ×3
ruby ×2
angularjs ×1
heroku ×1
mysql ×1
omniauth ×1
postgresql ×1