модуль ActiveModel
Active Model – интерфейсы моделей для Rails
Active Model предоставляет известный набор интерфейсов для использования в классах моделей. Например, они позволяют помощникам Action Pack взаимодействовать с моделями, не являющимися Active Record. Active Model также помогает создавать пользовательские ORM для использования вне фреймворка Rails.
Подробнее об Active Model можно прочитать в руководстве Основы Active Model.
До Rails 3.0 разработчику плагина или гем-пакета, желавшему, чтобы объект взаимодействовал с помощниками Action Pack, приходилось либо копировать фрагменты кода из Rails, либо обезьянить целые помощники, чтобы они могли работать с объектами, которые не полностью соответствовали интерфейсу Active Record. Это приводило к дублированию кода и ненадёжным приложениям, которые переставали работать после обновлений. Active Model решает эту проблему, определяя явный API. Подробнее о API можно прочитать в разделе ActiveModel::Lint::Tests.
Active Model предоставляет модуль по умолчанию, реализующий базовый API, необходимый для взаимодействия с Action Pack «из коробки»: ActiveModel::API.
class Person include ActiveModel::API attr_accessor :name, :age validates_presence_of :name end person = Person.new(name: 'bob', age: '18') person.name # => 'bob' person.age # => '18' person.valid? # => true
Он включает интроспекцию имён моделей, преобразования, переводы и валидации, в результате чего получается класс, подходящий для использования с Action Pack. Дополнительные примеры см. в разделе ActiveModel::API.
Active Model также предоставляет следующие возможности, обеспечивающие поведение ORM «из коробки»:
-
Добавление в объекты магии атрибутов
class Person include ActiveModel::AttributeMethods attribute_method_prefix 'clear_' define_attribute_methods :name, :age attr_accessor :name, :age def clear_attribute(attr) send("#{attr}=", nil) end end person = Person.new person.clear_name person.clear_age -
Callbacksдля определённых операцийclass Person extend ActiveModel::Callbacks define_model_callbacks :create def create run_callbacks :create do # Your create action methods here end end endЭто создаёт методы класса
before_create,around_createиafter_create, оборачивающие ваш метод создания. -
Отслеживание изменений значений
class Person include ActiveModel::Dirty define_attribute_methods :name def name @name end def name=(val) name_will_change! unless val == @name @name = val end def save # do persistence work changes_applied end end person = Person.new person.name # => nil person.changed? # => false person.name = 'bob' person.changed? # => true person.changed # => ['name'] person.changes # => { 'name' => [nil, 'bob'] } person.save person.name = 'robert' person.save person.previous_changes # => {'name' => ['bob, 'robert']} -
Добавление интерфейса
errorsк объектамПредоставление сообщений об ошибках позволяет объектам беспрепятственно взаимодействовать с помощниками Action Pack.
class Person def initialize @errors = ActiveModel::Errors.new(self) end attr_accessor :name attr_reader :errors def validate! errors.add(:name, "cannot be nil") if name.nil? end def self.human_attribute_name(attr, options = {}) "Name" end end person = Person.new person.name = nil person.validate! person.errors.full_messages # => ["Name cannot be nil"] -
Интроспекция имён
Modelclass NamedPerson extend ActiveModel::Naming end NamedPerson.model_name.name # => "NamedPerson" NamedPerson.model_name.human # => "Named person"
-
Сериализация объектов
ActiveModel::Serializationпредоставляет стандартный интерфейс, позволяющий объекту выполнять сериализациюto_json.class SerialPerson include ActiveModel::Serialization attr_accessor :name def attributes {'name' => name} end end s = SerialPerson.new s.serializable_hash # => {"name"=>nil} class SerialPerson include ActiveModel::Serializers::JSON end s = SerialPerson.new s.to_json # => "{\"name\":null}" -
Поддержка интернационализации (i18n)
class Person extend ActiveModel::Translation end Person.human_attribute_name('my_attribute') # => "My attribute" -
Поддержка валидации
class Person include ActiveModel::Validations attr_accessor :first_name, :last_name validates_each :first_name, :last_name do |record, attr, value| record.errors.add attr, "starts with z." if value.start_with?("z") end end person = Person.new person.first_name = 'zoolander' person.valid? # => false -
Пользовательские валидаторы
class HasNameValidator < ActiveModel::Validator def validate(record) record.errors.add(:name, "must exist") if record.name.blank? end end class ValidatorPerson include ActiveModel::Validations validates_with HasNameValidator attr_accessor :name end p = ValidatorPerson.new p.valid? # => false p.errors.full_messages # => ["Name must exist"] p.name = "Bob" p.valid? # => true
Загрузка и установка
Последнюю версию Active Model можно установить с помощью RubyGems:
$ gem install activemodel
Исходный код можно скачать в составе проекта Rails на GitHub
Лицензия
Active Model распространяется по лицензии MIT:
Поддержка
Документация API находится по адресу:
Сообщить об ошибках в проекте Ruby on Rails можно здесь:
Предложения по новым функциям следует обсуждать на форуме rubyonrails-core здесь:
Открытые методы класса
# File activemodel/lib/active_model.rb, line 82 def self.eager_load! super ActiveModel::Serializers.eager_load! end
# File activemodel/lib/active_model/gem_version.rb, line 5 def self.gem_version Gem::Version.new VERSION::STRING end
Возвращает текущую загруженную версию Active Model в виде Gem::Version.
# File activemodel/lib/active_model/version.rb, line 7 def self.version gem_version end
Возвращает текущую загруженную версию Active Model в виде Gem::Version.
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.