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 來解決此問題。您可以在 ActiveModel::Lint::Tests
了解有關 API 的更多資訊。
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
-
特定操作的呼叫回函
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
類別方法,以包裹您的 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"]
-
模型名稱內省
class 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
下載及安裝
可以使用 RubyGems 安裝最新版本的 Active Model
$ gem install activemodel
可以從 GitHub 上的 Rails 專案下載原始碼
授權
Active Model 是根據 MIT 授權發布的
支援
API 文件位於
Ruby on Rails 專案的錯誤報告可以在此處提交
功能要求應在 rails-core 郵寄清單上討論