如何使用 Rails 6.1 多数据库 ActiveRecord::ConnectionHandling 连接到主数据库和分片?

问题描述

我正在尝试构建一个应用程序,该应用程序将使用最新的 Rails 6.1 功能之一:multiple databases - 您可以在底部阅读源代码。

我想通过能够根据请求域在数据库之间切换来实现多租户。

每个俱乐部都有自己的数据库,一个主数据库将存储用户、俱乐部等特定于应用的数据。

我创建了两种类型的记录:使用 GlobalRecord 数据库的 primary 和使用水平分片数据库的 ShardRecord

并且还尝试使用 around_action 选择当前俱乐部数据库。

# config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode

development:
  primary:
    <<: *default
    database: primary
    migrations_paths: db/migrate
  club_1:
    <<: *default
    database: club_1
    migrations_paths: db/shard_migrate
  club_2:
    <<: *default
    database: club_2
    host: 1.1.1.1
    username: deploy
    password: pass
    migrations_paths: db/shard_migrate
class Club < GlobalRecord; end
class GlobalRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to shards: {
    club_1: { writing: :primary,reading: :primary },club_2: { writing: :primary,reading: :primary }
  }
end
class MemberRecord < ShardRecord; end
class ShardRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to shards: {
    club_1: { writing: :club_1,reading: :club_1 },club_2: { writing: :club_2,reading: :club_2 }
  }
end
class ApplicationController < ActionController::API
  before_action :set_club
  around_action :connect_to_shard

  private

  def set_club
    @club = SelectClubByDomain.new(request).slug
  end

  def connect_to_shard
    ActiveRecord::Base.connected_to(role: :writing,shard: @club.slug) do
      yield
    end
  end
end

我有几个设计问题要问您:

  1. 我想将 GlobalRecord 设置为 connects_to database: { writing: :primary } 但因为我添加了 around_action 我必须像上面那样设置。 这是糟糕的设计吗? 我可以重构它以便我可以在没有 ActiveRecord::Base.connected_to(role: :writing,shard: :club_1) 块的情况下始终调用 GlobalRecord 吗?

尝试在 ActiveRecord::Base.connected_to_many(GlobalRecord,ShardRecord,role: :writing,shard: @club_slug.to_sym) 中使用 around_action 但根据请求 (clubs#index => [Club.all]) 我收到错误:

ActiveRecord::ConnectionNotEstablished (No connection pool for 'GlobalRecord' found for the 'club_1' shard.)
  1. 在启动的生产服务器上,我看到此警告,如何解决?
=> Run `bin/rails server --help` for more startup options
Failed to define attribute methods because of ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished

来源:

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)