Spec-Zone.ru › Ruby on Rails 8.1

module ActiveRecord::Core

Ядро Active Record

Атрибуты

strict_loading_mode [R]

Открытые методы класса

attributes_for_inspect () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 118
class_attribute :attributes_for_inspect, instance_accessor: false, default: :all

Задает атрибуты, которые будут включены в вывод метода inspect:

Post.attributes_for_inspect = [:id, :title]
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"

Если задано значение :all, метод inspect выведет список всех атрибутов записи:

Post.attributes_for_inspect = :all
Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
configurations () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 76
def self.configurations
  @@configurations
end

Возвращает полностью разрешенный объект ActiveRecord::DatabaseConfigurations.

configurations= (config) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 70
def self.configurations=(config)
  @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
end

Содержит конфигурацию базы данных — обычно она хранится в config/database.yml — в виде объекта ActiveRecord::DatabaseConfigurations.

Например, следующий файл database.yml…

development:
  adapter: sqlite3
  database: storage/development.sqlite3

production:
  adapter: sqlite3
  database: storage/production.sqlite3

…приведет к тому, что ActiveRecord::Base.configurations будет выглядеть так:

#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
    @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
    @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
]>
connection_handler () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 132
def self.connection_handler
  ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
end
connection_handler= (handler) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 136
def self.connection_handler=(handler)
  ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
end
current_preventing_writes () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 195
def self.current_preventing_writes
  connected_to_stack.reverse_each do |hash|
    return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
    return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
  end

  false
end

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

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_preventing_writes #=> true
end

ActiveRecord::Base.connected_to(role: :writing) do
  ActiveRecord::Base.current_preventing_writes #=> false
end
current_role () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 158
def self.current_role
  connected_to_stack.reverse_each do |hash|
    return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
    return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
  end

  default_role
end

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

ActiveRecord::Base.connected_to(role: :writing) do
  ActiveRecord::Base.current_role #=> :writing
end

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_role #=> :reading
end
current_shard () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 176
def self.current_shard
  connected_to_stack.reverse_each do |hash|
    return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
    return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
  end

  default_shard
end

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

ActiveRecord::Base.connected_to(role: :reading) do
  ActiveRecord::Base.current_shard #=> :default
end

ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
  ActiveRecord::Base.current_shard #=> :one
end
destroy_association_async_batch_size () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 46
class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil

Задает максимальное число записей, удаляемых одним фоновым заданием при использовании параметра ассоциации dependent: :destroy_async. Если значение равно nil (по умолчанию), все зависимые записи будут удалены одним фоновым заданием. Если значение задано, записи для удаления будут распределены по нескольким фоновым заданиям.

destroy_association_async_job () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 26
def self.destroy_association_async_job
  if _destroy_association_async_job.is_a?(String)
    self._destroy_association_async_job = _destroy_association_async_job.constantize
  end
  _destroy_association_async_job
rescue NameError => error
  raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
end

Класс задания, используемый для фонового удаления ассоциаций.

enumerate_columns_in_select_statements () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 86
class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false

Принудительно перечисляет все столбцы в операторах SELECT. Например, SELECT first_name, last_name FROM ... вместо SELECT * FROM .... Это позволяет избежать ошибок PreparedStatementCacheExpired, если во время работы приложения в базу данных добавляется столбец.

logger () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 21
class_attribute :logger, instance_writer: false

Принимает регистратор, соответствующий интерфейсу Log4r или стандартному классу Ruby Logger, и передает его всем новым подключениям к базе данных. Получить этот регистратор можно, вызвав logger у класса модели Active Record или ее экземпляра.

new (attributes = nil) { |self| ... } Показать исходный код
# File activerecord/lib/active_record/core.rb, line 472
def initialize(attributes = nil)
  @new_record = true
  @attributes = self.class._default_attributes.deep_dup

  init_internals
  initialize_internals_callback

  super

  yield self if block_given?
  _run_initialize_callbacks
end

Новые объекты можно создавать пустыми (не передавая параметров конструктору) или с предварительно заданными атрибутами, но еще не сохраненными (передав хеш, имена ключей которого соответствуют именам столбцов связанной таблицы). В обоих случаях допустимые ключи атрибутов определяются именами столбцов связанной таблицы — поэтому атрибуты, отсутствующие среди столбцов таблицы, задать нельзя.

Пример

# Instantiates a single new object
User.new(first_name: 'Jamie')
Вызывает метод суперкласса

Открытые методы экземпляра

<=> (other_object) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 666
def <=>(other_object)
  if other_object.is_a?(self.class)
    to_key <=> other_object.to_key
  else
    super
  end
end

Позволяет сортировать объекты

Вызывает метод суперкласса
== (comparison_object) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 632
def ==(comparison_object)
  super ||
    comparison_object.instance_of?(self.class) &&
    primary_key_values_present? &&
    comparison_object.id == id
end

Возвращает true, если comparison_object является тем же самым объектом или если comparison_object имеет тот же тип, а self имеет идентификатор, равный comparison_object.id.

Обратите внимание: по определению новые записи отличаются от любых других записей, кроме случая, когда другая запись — это сам объект-получатель. Кроме того, если вы загружаете существующие записи с помощью select и не указываете идентификатор, действовать придется на свой страх и риск: этот предикат вернет false.

Также обратите внимание, что при удалении записи ее идентификатор сохраняется в экземпляре модели, поэтому удаленные модели по-прежнему можно сравнивать.

Вызывает метод суперкласса
Также имеет псевдоним: eql?
clone () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 524
    

Работает так же, как метод clone в Ruby. Это «поверхностная» копия. Обратите внимание: атрибуты не копируются. Это значит, что изменение атрибутов клона изменит и оригинал, поскольку оба объекта будут ссылаться на один и тот же хеш атрибутов. Если вам нужна копия хеша атрибутов, используйте метод dup.

user = User.first
new_user = user.clone
user.name               # => "Bob"
new_user.name = "Joe"
user.name               # => "Joe"

user.object_id == new_user.object_id            # => false
user.name.object_id == new_user.name.object_id  # => true

user.name.object_id == user.dup.name.object_id  # => false
connection_handler () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 771
def connection_handler
  self.class.connection_handler
end
dup () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 541
    

У дублированных объектов нет назначенного идентификатора, и они считаются новыми записями. Обратите внимание: это «поверхностная» копия — копируются только атрибуты объекта, но не его ассоциации. Глубина «глубокого» копирования зависит от приложения, поэтому его реализация остается на усмотрение приложения и определяется его потребностями. Метод dup не сохраняет временные метки (created|updated)_(at|on) и столбец блокировки.

encode_with (coder) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 588
def encode_with(coder)
  self.class.yaml_encoder.encode(@attributes, coder)
  coder["new_record"] = new_record?
  coder["active_record_yaml_version"] = 2
end

Заполняет coder атрибутами этой записи, которые следует сериализовать. Структура coder, определенная в этом методе, гарантированно соответствует структуре coder, передаваемого методу init_with.

Пример:

class Post < ActiveRecord::Base
end
coder = {}
Post.new.encode_with(coder)
coder # => {"attributes" => {"id" => nil, ... }}
eql? (comparison_object)
Псевдоним для: ==
freeze () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 655
def freeze
  @attributes = @attributes.clone.freeze
  self
end

Клонирует и замораживает хеш атрибутов, чтобы ассоциации оставались доступными даже у удаленных записей, но клонированные модели не замораживались.

frozen? () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 661
def frozen?
  @attributes.frozen?
end

Возвращает true, если хеш атрибутов заморожен.

full_inspect () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 795
def full_inspect
  inspect_with_attributes(all_attributes_for_inspect)
end

Возвращает все атрибуты записи в виде аккуратно отформатированной строки, игнорируя .attributes_for_inspect.

Post.first.full_inspect
#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
hash () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 642
def hash
  id = self.id

  if self.class.composite_primary_key? ? primary_key_values_present? : id
    self.class.hash ^ id.hash
  else
    super
  end
end

Перенаправляет вызов к идентификатору, чтобы две записи одного типа с одинаковым идентификатором могли использоваться, например, так:

[ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
Вызывает метод суперкласса
init_with (coder, &block) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 499
def init_with(coder, &block)
  coder = LegacyYamlAdapter.convert(coder)
  attributes = self.class.yaml_encoder.decode(coder)
  init_with_attributes(attributes, coder["new_record"], &block)
end

Инициализирует пустой объект модели из coder. coder должен быть результатом предварительной сериализации модели Active Record с помощью метода encode_with.

class Post < ActiveRecord::Base
end

old_post = Post.new(title: "hello world")
coder = {}
old_post.encode_with(coder)

post = Post.allocate
post.init_with(coder)
post.title # => 'hello world'
inspect () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 785
def inspect
  inspect_with_attributes(attributes_for_inspect)
end

Возвращает атрибуты записи в виде аккуратно отформатированной строки.

Post.first.inspect
#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"

Список атрибутов можно ограничить, задав .attributes_for_inspect.

Post.attributes_for_inspect = [:id, :title]
Post.first.inspect
#=> "#<Post id: 1, title: "Hello, World!">"
pretty_print (pp) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 801
def pretty_print(pp)
  return super if custom_inspect_method_defined?
  pp.object_address_group(self) do
    if @attributes
      attr_names = attributes_for_inspect.select { |name| _has_attribute?(name.to_s) }
      pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
        attr_name = attr_name.to_s
        pp.breakable " "
        pp.group(1) do
          pp.text attr_name
          pp.text ":"
          pp.breakable
          value = attribute_for_inspect(attr_name)
          pp.text value
        end
      end
    else
      pp.breakable " "
      pp.text "not initialized"
    end
  end
end

Принимает объект PP и выводит в него эту запись в отформатированном виде. Если подключен модуль pp, это позволяет получить удобочитаемый результат с помощью pp record.

Вызывает метод суперкласса
readonly! () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 767
def readonly!
  @readonly = true
end

Запрещает сохранять записи в базу данных:

customer = Customer.new
customer.readonly!
customer.save # raises ActiveRecord::ReadOnlyRecord

customer = Customer.first
customer.readonly!
customer.update(name: 'New Name') # raises ActiveRecord::ReadOnlyRecord

Записи только для чтения также нельзя удалить из базы данных:

customer = Customer.first
customer.readonly!
customer.destroy # raises ActiveRecord::ReadOnlyRecord

Обратите внимание: сами объекты по-прежнему можно изменять в памяти:

customer = Customer.new
customer.readonly!
customer.name = 'New Name' # OK

но сохранить изменения не получится.

readonly? () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 683
def readonly?
  @readonly
end

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

slice(*methods) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 595
    

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

topic = Topic.new(title: "Budget", author_name: "Jason")
topic.slice(:title, :author_name)
# => { "title" => "Budget", "author_name" => "Jason" }
strict_loading! (value = true, mode: :all) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 723
def strict_loading!(value = true, mode: :all)
  unless [:all, :n_plus_one_only].include?(mode)
    raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
  end

  @strict_loading_mode = mode
  @strict_loading = value
end

Включает для записи режим strict_loading. Если запись попытается лениво загрузить ассоциацию, будет вызвана ошибка.

ПРИМЕЧАНИЕ: во время валидации strict loading отключен, чтобы запись могла проверить свою ассоциацию.

user = User.first
user.strict_loading! # => true
user.address.city
# => ActiveRecord::StrictLoadingViolationError
user.comments.to_a
# => ActiveRecord::StrictLoadingViolationError

Параметры

  • value — логическое значение, задающее включение или отключение strict loading.

  • :mode — Symbol, задающий режим strict loading. По умолчанию используется :all. В режиме :n_plus_one_only ошибка будет вызвана только при ленивой загрузке ассоциации, которая приведет к запросу n плюс один.

Примеры

user = User.first
user.strict_loading!(false) # => false
user.address.city # => "Tatooine"
user.comments.to_a # => [#<Comment:0x00...]

user.strict_loading!(mode: :n_plus_one_only)
user.address.city # => "Tatooine"
user.comments.to_a # => [#<Comment:0x00...]
user.comments.first.ratings.to_a
# => ActiveRecord::StrictLoadingViolationError
strict_loading? () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 688
def strict_loading?
  @strict_loading
end

Возвращает true, если запись находится в режиме strict_loading.

strict_loading_all? () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 740
def strict_loading_all?
  @strict_loading_mode == :all
end

Возвращает true, если для записи используется strict_loading с включенным режимом :all.

strict_loading_n_plus_one_only? () Показать исходный код
# File activerecord/lib/active_record/core.rb, line 735
def strict_loading_n_plus_one_only?
  @strict_loading_mode == :n_plus_one_only
end

Возвращает true, если для записи используется strict_loading с включенным режимом :n_plus_one_only.

values_at(*methods) Показать исходный код
# File activerecord/lib/active_record/core.rb, line 610
    

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

topic = Topic.new(title: "Budget", author_name: "Jason")
topic.values_at(:title, :author_name)
# => ["Budget", "Jason"]

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

Spec-Zone.ru

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