модуль ActiveRecord::Core
Active Record Core
Атрибуты
Публичные методы класса
# File activerecord/lib/active_record/core.rb, line 77 def self.configurations @@configurations end
Возвращает полностью разрешённый объект ActiveRecord::DatabaseConfigurations.
# File activerecord/lib/active_record/core.rb, line 71 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"}>
]> # File activerecord/lib/active_record/core.rb, line 120 def self.connection_handler ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler end
# File activerecord/lib/active_record/core.rb, line 124 def self.connection_handler=(handler) ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler end
# File activerecord/lib/active_record/core.rb, line 183
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
# File activerecord/lib/active_record/core.rb, line 146
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
# File activerecord/lib/active_record/core.rb, line 164
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
# File activerecord/lib/active_record/core.rb, line 47 class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil
Устанавливает максимальное количество записей, которые будут уничтожены одной фоновой задачей опцией dependent: :destroy_async. При значении nil (по умолчанию) все зависимые записи будут уничтожены в одной фоновой задаче. При указанном значении записи для уничтожения будут разделены на несколько фоновых задач.
# File activerecord/lib/active_record/core.rb, line 27
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 Класс задачи, используемый для уничтожения ассоциаций в фоновом режиме.
# File activerecord/lib/active_record/core.rb, line 87 class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
Принудительное перечисление всех столбцов в операторах SELECT. Например, SELECT first_name, last_name FROM ..., а не SELECT * FROM .... Это предотвращает ошибки PreparedStatementCacheExpired, когда в базу данных добавляется столбец во время работы приложения.
# File activerecord/lib/active_record/core.rb, line 22 class_attribute :logger, instance_writer: false
Принимает логгер, соответствующий интерфейсу Log4r или по умолчанию Ruby Logger класс, который затем передаётся во все новые подключения к базе данных. Вы можете получить этот логгер, вызвав logger на классе модели Active Record или экземпляре модели Active Record.
# File activerecord/lib/active_record/core.rb, line 451 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')
Общедоступные методы экземпляров
# File activerecord/lib/active_record/core.rb, line 638
def <=>(other_object)
if other_object.is_a?(self.class)
to_key <=> other_object.to_key
else
super
end
end Позволяет сортировать объекты
# File activerecord/lib/active_record/core.rb, line 604
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.
Также обратите внимание, что уничтожение записи сохраняет её идентификатор в экземпляре модели, поэтому удалённые модели по-прежнему сравнимы.
# File activerecord/lib/active_record/core.rb, line 503
Идентично методу 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
# File activerecord/lib/active_record/core.rb, line 723 def connection_handler self.class.connection_handler end
# File activerecord/lib/active_record/core.rb, line 520
У дублированных объектов нет назначенного идентификатора, и они обрабатываются как новые записи. Обратите внимание, что это «поверхностная» копия, поскольку она копирует только атрибуты объекта, а не его ассоциации. Объем «глубокой» копии зависит от приложения, и поэтому реализация копии оставляется на усмотрение приложения в соответствии с его потребностями. Метод dup не сохраняет временные метки (created|updated)_(at|on) и столбец блокировки.
# File activerecord/lib/active_record/core.rb, line 560 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, ... }}
# File activerecord/lib/active_record/core.rb, line 627 def freeze @attributes = @attributes.clone.freeze self end
Создать копию и заморозить хэш атрибутов таким образом, что ассоциации по-прежнему доступны, даже для уничтоженных записей, но клонированные модели не будут заморожены.
# File activerecord/lib/active_record/core.rb, line 633 def frozen? @attributes.frozen? end
Возвращает true если хэш атрибутов был заморожен.
# File activerecord/lib/active_record/core.rb, line 733 def full_inspect inspect_with_attributes(attribute_names) end
Возвращает полное содержимое записи в виде отформатированной строки.
# File activerecord/lib/active_record/core.rb, line 614
def hash
id = self.id
if primary_key_values_present?
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) ]
# File activerecord/lib/active_record/core.rb, line 478 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'
# File activerecord/lib/active_record/core.rb, line 728 def inspect inspect_with_attributes(attributes_for_inspect) end
Возвращает атрибуты, указанные в .attributes_for_inspect, в виде отформатированной строки.
# File activerecord/lib/active_record/core.rb, line 739
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 record при необходимости pp.
# File activerecord/lib/active_record/core.rb, line 719 def readonly! @readonly = true end
Отмечает эту запись как только для чтения.
customer = Customer.first customer.readonly! customer.save # Raises an ActiveRecord::ReadOnlyRecord
# File activerecord/lib/active_record/core.rb, line 655 def readonly? @readonly end
Возвращает true если запись только для чтения.
# File activerecord/lib/active_record/core.rb, line 567
Возвращает хэш заданных методов с их именами в качестве ключей и возвращаемыми значениями в качестве значений.
topic = Topic.new(title: "Budget", author_name: "Jason")
topic.slice(:title, :author_name)
=> { "title" => "Budget", "author_name" => "Jason" } # File activerecord/lib/active_record/core.rb, line 693
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. Это вызовет ошибку, если запись попытается загрузить ассоциацию лениво.
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
# File activerecord/lib/active_record/core.rb, line 660 def strict_loading? @strict_loading end
Возвращает true если запись находится в режиме strict_loading.
# File activerecord/lib/active_record/core.rb, line 710 def strict_loading_all? @strict_loading_mode == :all end
Возвращает true, если запись использует strict_loading с включённым режимом :all.
# File activerecord/lib/active_record/core.rb, line 705 def strict_loading_n_plus_one_only? @strict_loading_mode == :n_plus_one_only end
Возвращает true, если запись использует strict_loading с включённым режимом :n_plus_one_only.
# File activerecord/lib/active_record/core.rb, line 582
Возвращает массив значений, возвращаемых заданными методами.
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.