Spec-Zone.ru › Ruby on Rails 7.0

модуль ActiveRecord::ConnectionHandling

Постоянные значения

DEFAULT_ENV
RAILS_ENV

Атрибуты

connection_specification_name[W]

Методы публичного экземпляра

clear_query_caches_for_current_thread() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 266
def clear_query_caches_for_current_thread
  if ActiveRecord.legacy_connection_handling
    ActiveRecord::Base.connection_handlers.each_value do |handler|
      clear_on_handler(handler)
    end
  else
    clear_on_handler(ActiveRecord::Base.connection_handler)
  end
end

Очищает кэш запросов для всех подключений, связанных с текущей нитью.

connected?() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 317
def connected?
  connection_handler.connected?(connection_specification_name, role: current_role, shard: current_shard)
end

Возвращает значение true, если Active Record подключен.

connected_to(role: nil, shard: nil, prevent_writes: false, &blk) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 137
def connected_to(role: nil, shard: nil, prevent_writes: false, &blk)
  if ActiveRecord.legacy_connection_handling
    if self != Base
      raise NotImplementedError, "`connected_to` can only be called on ActiveRecord::Base with legacy connection handling."
    end
  else
    if self != Base && !abstract_class
      raise NotImplementedError, "calling `connected_to` is only allowed on ActiveRecord::Base or abstract classes."
    end

    if name != connection_specification_name && !primary_class?
      raise NotImplementedError, "calling `connected_to` is only allowed on the abstract class that established the connection."
    end
  end

  unless role || shard
    raise ArgumentError, "must provide a `shard` and/or `role`."
  end

  with_role_and_shard(role, shard, prevent_writes, &blk)
end

Подключается к роли (например, записи, чтения или пользовательской роли) и/или фрагменту на время выполнения блока. По окончании блока подключение будет возвращено к исходной роли/фрагменту.

Если передана только роль, Active Record найдет подключение на основе запрошенной роли. Если запрошена не установленная роль, будет поднято исключение ActiveRecord::ConnectionNotEstablished:

ActiveRecord::Base.connected_to(role: :writing) do
  Dog.create! # creates dog using dog writing connection
end

ActiveRecord::Base.connected_to(role: :reading) do
  Dog.create! # throws exception because we're on a replica
end

При переключении на фрагмент также должна быть передана роль. Если передан несуществующий фрагмент, будет поднято исключение ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do Dog.first # finds first Dog record stored on the shard one replica end ">

ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do
  Dog.first # finds first Dog record stored on the shard one replica
end
.

Если переданы фрагмент и роль, Active Record сначала найдет роль, а затем найдет подключение по ключу фрагмента.

ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do
  Dog.first # finds first Dog record stored on the shard one replica
end
connected_to?(role:, shard: ActiveRecord::Base.default_shard) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 252
def connected_to?(role:, shard: ActiveRecord::Base.default_shard)
  current_role == role.to_sym && current_shard == shard.to_sym
end

Возвращает true, если роль является текущей подключенной ролью.

ActiveRecord::Base.connected_to(role: :writing) do
  ActiveRecord::Base.connected_to?(role: :writing) #=> true
  ActiveRecord::Base.connected_to?(role: :reading) #=> false
end
connected_to_many(*classes, role:, shard: nil, prevent_writes: false) { || ... } Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 172
def connected_to_many(*classes, role:, shard: nil, prevent_writes: false)
  classes = classes.flatten

  if ActiveRecord.legacy_connection_handling
    raise NotImplementedError, "connected_to_many is not available with legacy connection handling"
  end

  if self != Base || classes.include?(Base)
    raise NotImplementedError, "connected_to_many can only be called on ActiveRecord::Base."
  end

  prevent_writes = true if role == ActiveRecord.reading_role

  append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes)
  yield
ensure
  connected_to_stack.pop
end

Подключает роль и/или фрагмент к указанным именам подключений. Дополнительно можно передать параметр prevent_writes для блокировки записей в подключении. Параметр prevent_writes автоматически установит role в значение true.

Данный метод является альтернативой глубоко вложенным блокам.

Использование:

ActiveRecord::Base.connected_to_many(AnimalsRecord, MealsRecord, role: :reading) do
  Dog.first # Read from animals replica
  Dinner.first # Read from meals replica
  Person.first # Read from primary writer
end
connecting_to(role: default_role, shard: default_shard, prevent_writes: false) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 198
def connecting_to(role: default_role, shard: default_shard, prevent_writes: false)
  if ActiveRecord.legacy_connection_handling
    raise NotImplementedError, "`connecting_to` is not available with `legacy_connection_handling`."
  end

  prevent_writes = true if role == ActiveRecord.reading_role

  append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self])
end

Используйте указанное подключение.

Этот метод полезен для обеспечения использования конкретного подключения. Например, при запуске консоли в режиме только для чтения.

Использование этого метода в запросе не рекомендуется, поскольку он не возвращает результат в блоке, как # File activerecord/lib/active_record/connection_handling.rb, line 304 def connection_db_config connection_pool.db_config end">

# File activerecord/lib/active_record/connection_handling.rb, line 304
def connection_db_config
  connection_pool.db_config
end
.

connection() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 279
def connection
  retrieve_connection
end

Возвращает подключение, в настоящее время связанное с классом. Это также можно использовать для «заимствования» подключения для выполнения работы с базой данных, не связанной с конкретными Active Record.

connection_db_config() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 304
def connection_db_config
  connection_pool.db_config
end

Возвращает объект db_config из связанного подключения:

ActiveRecord::Base.connection_db_config
  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
    @name="primary", @config={pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}>

Используйте только для чтения.

connection_pool() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 308
def connection_pool
  connection_handler.retrieve_connection_pool(connection_specification_name, role: current_role, shard: current_shard) || raise(ConnectionNotEstablished)
end
connection_specification_name() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 286
def connection_specification_name
  if !defined?(@connection_specification_name) || @connection_specification_name.nil?
    return self == Base ? Base.name : superclass.connection_specification_name
  end
  @connection_specification_name
end

Возвращает имя спецификации подключения из текущего класса или его родителя.

connects_to(database: {}, shards: {}) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 81
def connects_to(database: {}, shards: {})
  raise NotImplementedError, "`connects_to` can only be called on ActiveRecord::Base or abstract classes" unless self == Base || abstract_class?

  if database.present? && shards.present?
    raise ArgumentError, "`connects_to` can only accept a `database` or `shards` argument, but not both arguments."
  end

  connections = []

  database.each do |role, database_key|
    db_config, owner_name = resolve_config_for_connection(database_key)
    handler = lookup_connection_handler(role.to_sym)

    self.connection_class = true
    connections << handler.establish_connection(db_config, owner_name: owner_name, role: role)
  end

  shards.each do |shard, database_keys|
    database_keys.each do |role, database_key|
      db_config, owner_name = resolve_config_for_connection(database_key)
      handler = lookup_connection_handler(role.to_sym)

      self.connection_class = true
      connections << handler.establish_connection(db_config, owner_name: owner_name, role: role, shard: shard.to_sym)
    end
  end

  connections
end

Подключает модель к указанным базам данных. Ключевое слово database принимает хеш, состоящий из параметров подключения и роли.

Это создаст обработчик подключений для переключения между подключениями, найдет хеш конфигурации с помощью database и, наконец, установит подключение к этой конфигурации.

class AnimalsModel < ApplicationRecord
  self.abstract_class = true

  connects_to database: { writing: :primary, reading: :primary_replica }
end

Метод connects_to также поддерживает горизонтальное фрагментирование. API горизонтального фрагментирования также поддерживает реплики чтения. Подключите модель к списку фрагментов так:

class AnimalsModel < ApplicationRecord
  self.abstract_class = true

  connects_to shards: {
    default: { writing: :primary, reading: :primary_replica },
    shard_two: { writing: :primary_shard_two, reading: :primary_shard_replica_two }
  }
end

Возвращает массив подключений к базам данных.

establish_connection(config_or_env = nil) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 49
def establish_connection(config_or_env = nil)
  config_or_env ||= DEFAULT_ENV.call.to_sym
  db_config, owner_name = resolve_config_for_connection(config_or_env)
  connection_handler.establish_connection(db_config, owner_name: owner_name, role: current_role, shard: current_shard)
end

Устанавливает подключение к базе данных. Принимает хеш в качестве входных данных, где ключ adapter должен быть указан с именем адаптера базы данных (в нижнем регистре), например, для обычных баз данных (MySQL, PostgreSQL и т. д.):

ActiveRecord::Base.establish_connection(
  adapter:  "mysql2",
  host:     "localhost",
  username: "myuser",
  password: "mypass",
  database: "somedatabase"
)

Пример для базы данных SQLite:

ActiveRecord::Base.establish_connection(
  adapter:  "sqlite3",
  database: "path/to/dbfile"
)

Также принимает ключи в виде строк (например, для разбора из YAML):

ActiveRecord::Base.establish_connection(
  "adapter"  => "sqlite3",
  "database" => "path/to/dbfile"
)

Или URL:

ActiveRecord::Base.establish_connection(
  "postgres://myuser:mypass@localhost/somedatabase"
)

В случае, если ActiveRecord::Base.configurations установлен (Rails автоматически загружает содержимое config/database.yml в него), в качестве аргумента также может быть указана символьная переменная, представляющая ключ в хеше конфигурации:

ActiveRecord::Base.establish_connection(:production)

Исключения AdapterNotSpecified, AdapterNotFound и ArgumentError могут быть возвращены при ошибке.

prohibit_shard_swapping(enabled = true) { || ... } Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 214
def prohibit_shard_swapping(enabled = true)
  prev_value = ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
  ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = enabled
  yield
ensure
  ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = prev_value
end

Запрещает переключение фрагментов во время выполнения переданного блока.

В некоторых случаях вам может потребоваться возможность переключения фрагментов, но не разрешать вложенный вызов connected_to или connected_to_many для повторного переключения. Это полезно в тех случаях, когда вы используете фрагментацию для обеспечения изоляции базы данных на каждый запрос.

remove_connection(name = nil) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 321
def remove_connection(name = nil)
  name ||= @connection_specification_name if defined?(@connection_specification_name)
  # if removing a connection that has a pool, we reset the
  # connection_specification_name so it will use the parent
  # pool.
  if connection_handler.retrieve_connection_pool(name, role: current_role, shard: current_shard)
    self.connection_specification_name = nil
  end

  connection_handler.remove_connection_pool(name, role: current_role, shard: current_shard)
end
retrieve_connection() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 312
def retrieve_connection
  connection_handler.retrieve_connection(connection_specification_name, role: current_role, shard: current_shard)
end
shard_swapping_prohibited?() Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 223
def shard_swapping_prohibited?
  ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
end

Определяет, запрещено ли в настоящее время переключение фрагментов.

while_preventing_writes(enabled = true, &block) Показать исходный код
# File activerecord/lib/active_record/connection_handling.rb, line 238
def while_preventing_writes(enabled = true, &block)
  if ActiveRecord.legacy_connection_handling
    connection_handler.while_preventing_writes(enabled, &block)
  else
    connected_to(role: current_role, prevent_writes: enabled, &block)
  end
end

Запретить запись в базу данных независимо от роли.

В некоторых случаях вам может потребоваться предотвратить запись в базу данных, даже если вы подключены к базе, которая может записывать. Этот метод предотвратит запись в базу данных на время выполнения блока.

Этот метод не предоставляет той же защиты, что и пользователь только для чтения, и предназначен для защиты от случайных записей.

См. READ_QUERY для запросов, которые заблокированы этим методом.

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API