модуль ActiveRecord
Active Record – Отображение объекта-реляционной модели в Rails
Active Record подключает классы к таблицам реляционной базы данных, чтобы создать почти что безконфигурационный слой сохранения для приложений. Библиотека предоставляет базовый класс, который, при наследовании, устанавливает отображение между новым классом и существующей таблицей в базе данных. В контексте приложения эти классы обычно называются моделями. Модели также могут быть связаны с другими моделями; это делается путём определения ассоциаций.
Active Record сильно зависит от именования, поскольку использует имена классов и ассоциаций для установления отображения между соответствующими таблицами базы данных и столбцами внешних ключей. Хотя эти отображения можно определить явно, рекомендуется следовать соглашениям об именовании, особенно при знакомстве с библиотекой.
Подробнее об Active Record можно прочитать в руководстве Основы Active Record.
Краткое описание некоторых основных функций:
-
Автоматическое отображение между классами и таблицами, атрибутами и столбцами.
class Product < ActiveRecord::Base end
Класс Product автоматически отображается в таблицу с именем «products», которая может выглядеть так:
CREATE TABLE products ( id bigint NOT NULL auto_increment, name varchar(255), PRIMARY KEY (id) );
Это также определит следующие аксессоры:
Product#nameиProduct#name=(new_name). -
Associationsмежду объектами, определенными простыми методами класса.class Firm < ActiveRecord::Base has_many :clients has_one :account belongs_to :conglomerate end
-
Aggregationsобъектных значений.class Account < ActiveRecord::Base composed_of :balance, class_name: 'Money', mapping: %w(balance amount) composed_of :address, mapping: [%w(address_street street), %w(address_city city)] end -
Правила валидации, которые могут отличаться для новых или существующих объектов.
class Account < ActiveRecord::Base validates :subdomain, :name, :email_address, :password, presence: true validates :subdomain, uniqueness: true validates :terms_of_service, acceptance: true, on: :create validates :password, :email_address, confirmation: true, on: :create end
-
Callbacksдоступны для всего жизненного цикла (создание, сохранение, уничтожение, проверка и т.д.).class Person < ActiveRecord::Base before_destroy :invalidate_payment_plan # the `invalidate_payment_plan` method gets called just before Person#destroy end
-
Inheritanceиерархии.class Company < ActiveRecord::Base; end class Firm < Company; end class Client < Company; end class PriorityClient < Client; end
-
# Database transaction Account.transaction do david.withdrawal(100) mary.deposit(100) end
-
Рефлексия столбцов, ассоциаций и агрегаций.
reflection = Firm.reflect_on_association(:clients) reflection.klass # => Client (class) Firm.columns # Returns an array of column descriptors for the firms table
-
Абстракция базы данных через простые адаптеры.
# connect to SQLite3 ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'dbfile.sqlite3') # connect to MySQL with authentication ActiveRecord::Base.establish_connection( adapter: 'mysql2', host: 'localhost', username: 'me', password: 'secret', database: 'activerecord' )
Подробнее и прочитайте о встроенной поддержке MySQL, PostgreSQL и SQLite3.
-
Поддержка регистрации для Log4r и Logger.
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT) ActiveRecord::Base.logger = Log4r::Logger.new('Application Log') -
Управление схемой базы данных, независимое от базы данных, с помощью миграций.
class AddSystemSettings < ActiveRecord::Migration[8.0] def up create_table :system_settings do |t| t.string :name t.string :label t.text :value t.string :type t.integer :position end SystemSetting.create name: 'notice', label: 'Use notice?', value: 1 end def down drop_table :system_settings end end
Философия
Active Record – это реализация одноимённого паттерна отображения объекта-реляционной модели (ORM), описанного Мартином Фаулером:
«Объект, который оборачивает строку в таблице или представлении базы данных, инкапсулирует доступ к базе данных и добавляет логику домена к этим данным.»
Active Record пытается предоставить согласованный оболочку как решение для неудобств, связанных с отображением объекта-реляционной модели. Основной задачей этого отображения было минимизировать количество кода, необходимого для построения реальной модели домена. Это стало возможным благодаря использованию ряда соглашений, которые позволяют Active Record легко выводить сложные отношения и структуры из минимального количества явных инструкций.
Конвенция вместо конфигурации:
-
Нет файлов XML!
-
Много рефлексии и расширений во время выполнения
-
Магия – не обязательно плохое слово
Признавайте базу данных:
-
Позволяет использовать SQL для особых случаев и производительности
-
Не пытается дублировать или заменять определения данных
Загрузка и установка
Последнюю версию Active Record можно установить с помощью RubyGems:
$ gem install activerecord
Исходный код можно загрузить как часть проекта Rails на GitHub:
Лицензия
Active Record распространяется под лицензией MIT:
Поддержка
Документация API находится по адресу:
Отчеты об ошибках для проекта Ruby on Rails можно подать здесь:
Заявки на новые функции следует обсудить на почтовом списке rails-core здесь:
Класс ошибок валидации для обертывания ошибок записей ассоциаций, с поддержкой index_errors.
Константы
- MigrationProxy
-
MigrationProxyиспользуется для отложенной загрузки фактических классов миграций до тех пор, пока они не понадобятся - Point
- UnknownAttributeError
-
Active Model UnknownAttributeError
Вызывается, когда неизвестные атрибуты предоставляются через привязку к нескольким полям.
class Person include ActiveModel::AttributeAssignment include ActiveModel::Validations end person = Person.new person.assign_attributes(name: 'Gorby') # => ActiveModel::UnknownAttributeError: unknown attribute 'name' for Person.
Атрибуты
Публичные методы класса
# File activerecord/lib/active_record.rb, line 361 singleton_class.attr_accessor :action_on_strict_loading_violation
Устанавливает для приложения ведение журнала или генерацию исключения, когда ассоциация нарушает строгую загрузку. По умолчанию: :raise.
# File activerecord/lib/active_record.rb, line 527
def self.after_all_transactions_commit(&block)
open_transactions = all_open_transactions
if open_transactions.empty?
yield
elsif open_transactions.size == 1
open_transactions.first.after_commit(&block)
else
count = open_transactions.size
callback = -> do
count -= 1
block.call if count.zero?
end
open_transactions.each do |t|
t.after_commit(&callback)
end
open_transactions = nil # rubocop:disable Lint/UselessAssignment avoid holding it in the closure
end
end Регистрирует блок, который будет вызван после подтверждения всех текущих транзакций.
Если открытых транзакций нет, блок вызывается немедленно.
Если есть несколько вложенных транзакций, блок вызывается после подтверждения самой внешней из них.
Если какая-либо из текущих открытых транзакций отменена, блок никогда не вызывается.
Если открыто несколько транзакций в нескольких базах данных, блок будет вызван, если и когда все они будут подтверждены. Но обратите внимание, что вложение транзакций в двух разных базах данных является антипаттерном шардинга, который влечет за собой массу проблем.
# File activerecord/lib/active_record.rb, line 283 singleton_class.attr_accessor :async_query_executor
Устанавливает async_query_executor для приложения. По умолчанию используется пул потоков, установленный на nil, который не будет запускать запросы в фоновом режиме. Приложения должны настроить пул потоков, чтобы использовать эту функцию. Варианты:
* nil - Does not initialize a thread pool executor. Any async calls will be run in the foreground. * :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+ that uses the +async_query_concurrency+ for the +max_threads+ value. * :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each database connection. The initializer values are defined in the configuration hash.
# File activerecord/lib/active_record.rb, line 233 singleton_class.attr_reader :db_warnings_action
Действие, которое необходимо предпринять, когда запрос к базе данных создает предупреждение. Должно быть одним из :ignore, :log, :raise, :report или пользовательским процем. По умолчанию: :ignore.
# File activerecord/lib/active_record.rb, line 235
def self.db_warnings_action=(action)
@db_warnings_action =
case action
when :ignore
nil
when :log
->(warning) do
warning_message = "[#{warning.class}] #{warning.message}"
warning_message += " (#{warning.code})" if warning.code
ActiveRecord::Base.logger.warn(warning_message)
end
when :raise
->(warning) { raise warning }
when :report
->(warning) { Rails.error.report(warning, handled: true) }
when Proc
action
else
raise ArgumentError, "db_warnings_action must be one of :ignore, :log, :raise, :report, or a custom proc."
end
end # File activerecord/lib/active_record.rb, line 262 singleton_class.attr_accessor :db_warnings_ignore
Укажите разрешённый список предупреждений базы данных.
# File activerecord/lib/active_record.rb, line 218
def self.default_timezone=(default_timezone)
unless %i(local utc).include?(default_timezone)
raise ArgumentError, "default_timezone must be either :utc (default) or :local."
end
@default_timezone = default_timezone
end Определяет, использовать ли Time.utc (с помощью :utc) или Time.local (с помощью :local) при извлечении дат и времени из базы данных. По умолчанию установлено значение :utc.
# File activerecord/lib/active_record.rb, line 510 def self.disconnect_all! ConnectionAdapters::PoolConfig.disconnect_all! end
Явно закрывает все соединения с базой данных во всех пулах.
# File activerecord/lib/active_record.rb, line 409 singleton_class.attr_accessor :dump_schema_after_migration
Указывает, следует ли выполнять дамп схемы в конце команды bin/rails db:migrate. По умолчанию это значение равно true, что полезно для среды разработки. В производственной среде это значение должно быть false, так как дамп схемы редко требуется.
# File activerecord/lib/active_record.rb, line 419 singleton_class.attr_accessor :dump_schemas
Указывает, какие схемы базы данных необходимо дампать при вызове db:schema:dump. Если значение равно :schema_search_path (по умолчанию), дампаются все схемы, перечисленные в schema_search_path. Используйте :all, чтобы дампать все схемы независимо от schema_search_path, или строку с разделенными запятыми схемами для пользовательского списка.
# File activerecord/lib/active_record.rb, line 499 def self.eager_load! super ActiveRecord::Locking.eager_load! ActiveRecord::Scoping.eager_load! ActiveRecord::Associations.eager_load! ActiveRecord::AttributeMethods.eager_load! ActiveRecord::ConnectionAdapters.eager_load! ActiveRecord::Encryption.eager_load! end
# File activerecord/lib/active_record.rb, line 380 singleton_class.attr_accessor :error_on_ignored_order
Указывает, следует ли генерировать ошибку, если запрос имеет порядок, игнорируемый при выполнении пакетных запросов. Полезно в приложениях, где игнорируемая область является причиной ошибки, а не предупреждения.
# File activerecord/lib/active_record/gem_version.rb, line 5 def self.gem_version Gem::Version.new VERSION::STRING end
Возвращает текущую загруженную версию Active Record в виде Gem::Version.
# File activerecord/lib/active_record.rb, line 460 singleton_class.attr_accessor :generate_secure_token_on
Управляет тем, когда генерировать значение для объявлений has_secure_token. По умолчанию :create.
# File activerecord/lib/active_record.rb, line 298
def self.global_executor_concurrency=(global_executor_concurrency)
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
end
@global_executor_concurrency = global_executor_concurrency
end Устанавливает global_executor_concurrency. Это значение конфигурации можно использовать только с глобальным пулом потоков асинхронного выполнения запросов.
# File activerecord/lib/active_record.rb, line 189 singleton_class.attr_accessor :lazily_load_schema_cache
Ленивая загрузка кеша схемы. Этот параметр загрузит кеш схемы при установлении соединения, а не при загрузке.
# File activerecord/lib/active_record.rb, line 463 def self.marshalling_format_version Marshalling.format_version end
# File activerecord/lib/active_record.rb, line 467 def self.marshalling_format_version=(value) Marshalling.format_version = value end
# File activerecord/lib/active_record.rb, line 400 singleton_class.attr_accessor :migration_strategy
Укажите стратегию для выполнения миграций.
# File activerecord/lib/active_record.rb, line 314
def self.permanent_connection_checkout=(value)
unless [true, :deprecated, :disallowed].include?(value)
raise ArgumentError, "permanent_connection_checkout must be one of: `true`, `:deprecated` or `:disallowed`"
end
@permanent_connection_checkout = value
end Определяет, разрешен ли ActiveRecord::Base.connection, устарел или полностью запрещен.
# File activerecord/lib/active_record.rb, line 490 singleton_class.attr_accessor :protocol_adapters
Предоставляет отображение между протоколами баз данных/СУБД и используемым адаптером базы данных. Это используется только переменной окружения DATABASE_URL.
Пример
DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
Вышеуказанный URL указывает, что желаемым протоколом/СУБД является MySQL, и конфигурация приложения может затем решить, какой адаптер использовать. Для этого примера значение по умолчанию - отображение от mysql до mysql2, но также поддерживается :trilogy.
ActiveRecord.protocol_adapters.mysql = "mysql2"
Имена протоколов произвольные, и внешние адаптеры баз данных могут быть зарегистрированы и установлены здесь.
# File activerecord/lib/active_record.rb, line 336 singleton_class.attr_accessor :queues
Указывает имена очередей, используемых фоновыми задачами.
# File activerecord/lib/active_record.rb, line 446 singleton_class.attr_accessor :raise_int_wider_than_64bit
Конфигурируемый в приложении булевый параметр, определяющий, следует ли генерировать исключение, когда PostgreSQLAdapter получает целое число, которое шире, чем представление со знаком 64 бит.
# File activerecord/lib/active_record.rb, line 205
def self.schema_cache_ignored_table?(table_name)
ActiveRecord.schema_cache_ignored_tables.any? do |ignored|
ignored === table_name
end
end Проверяет, игнорируется ли table_name , проверяя по опции schema_cache_ignored_tables.
ActiveRecord.schema_cache_ignored_table?(:developers)
# File activerecord/lib/active_record.rb, line 197 singleton_class.attr_accessor :schema_cache_ignored_tables
Список таблиц или регулярных выражений для сопоставления таблиц, которые нужно игнорировать при выгрузке кэша схемы. Например, если это установлено в +[/^_/]+, кэш схемы не будет выгружать таблицы, имена которых содержат знак подчеркивания.
# File activerecord/lib/active_record.rb, line 372 singleton_class.attr_accessor :schema_format
Указывает формат, который нужно использовать при выгрузке схемы базы данных с помощью Rakefile Rails. Если :sql, схема выгружается как (возможно, специфичные для базы данных) SQL-запросы. Если :ruby, схема выгружается как файл ActiveRecord::Schema, который можно загрузить в любую базу данных, которая поддерживает миграции. Используйте :ruby, если вы хотите иметь разные адаптеры баз данных для, например, ваших сред разработки и тестирования.
# File activerecord/lib/active_record.rb, line 386 singleton_class.attr_accessor :timestamped_migrations
Указывает, использовать ли метки времени для версий миграций
# File activerecord/lib/active_record.rb, line 438 singleton_class.attr_accessor :use_yaml_unsafe_load
Конфигурируемый в приложении булевый параметр, который инструктирует кодировщик YAML использовать небезопасную загрузку, если он установлен в true.
# File activerecord/lib/active_record.rb, line 394 singleton_class.attr_accessor :validate_migration_timestamps
Указывает, следует ли проверять временные метки миграций. При установке параметра будет выведено исключение, если временная метка больше, чем на день опережает временную метку, связанную с текущим временем. timestamped_migrations должен быть установлен в true.
# File activerecord/lib/active_record.rb, line 329 singleton_class.attr_accessor :verbose_query_logs
Указывает, следует ли регистрировать методы, вызывающие запросы к базе данных, ниже соответствующих запросов. По умолчанию false.
# File activerecord/lib/active_record.rb, line 428 singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
Если true, Rails проверит все внешние ключи в базе данных после загрузки фикстур. Будет выведено исключение, если есть нарушения внешних ключей, что указывает на неправильно написанные фикстуры. Поддерживается PostgreSQL и SQLite.
# File activerecord/lib/active_record/version.rb, line 7 def self.version gem_version end
Возвращает загруженную версию Active Record в виде Gem::Version.
# File activerecord/lib/active_record.rb, line 453 singleton_class.attr_accessor :yaml_column_permitted_classes
Конфигурируемый в приложении массив, который предоставляет дополнительные разрешенные классы для Psych safe_load в кодировщике YAML
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.