المكتبة Active Model في ريلز
يوفر Active Model مجموعة معروفة من الواجهات لاستعمالها في أصناف النماذج (model classes). إنها تسمح لمساعدي Action Pack بالتفاعل مع النماذج التي ليست من Active Record مثلًا. يساعد Active Model في بناء روابط ORM مخصصة (تقنية ربط الكائنات بالعلاقات) للاستعمال خارج إطار ريلز.
يمكنك قراءة المزيد حول Active Model في دليل أساسيات Active Model.
قبل الإصدار 3.0 من ريلز، إن رغبت جوهرة أو رغب مطور بامتلاك كائن يتفاعل مع مساعدي Action Pack، فإنه يتطلب إمَّا نسخ أجزاء من شيفرة ريلز، أو استخدام ترقيع القرد (monkey patch) على كامل المساعدين لجعلهم يتعاملون مع كائنات لا تتوافق تمامًا مع واجهة Active Record. سيؤدي هذا إلى تكرارٍ في الشيفرة والحصول على تطبيق ضعيف، لذا جاءت الإصدارات اللاحقة مع Active Model الذي يحل هذه المعضلة عبر تعريف واجهة برمجية واضحة. يمكنك قراءة المزيد حول الواجهة البرمجية في ActiveModel::Lint::Tests
.
يوفر Active Model وحدة افتراضية تُنفِّذ الواجهة البرمجية الأساسية المطلوبة لدمج وتكامل Active Model بشكل خارج عن ما هو متعارف عليه: ActiveModel::Model
.
class Person
include ActiveModel::Model
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::Model
لمزيد من الأمثلة.
يوفر Active Model أيضًا الوظائف التالية لتأمين سلوك شبيه بسلوك ORM:
- إضافة خاصية سحرية (attribute magic) إلى الكائنات:
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
# هنا create ضع توابع الإجراء
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"
- جعل الكائنات قابلة للسَلسَلة (serializable):
يوفر 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}"
- دعم التدويل:
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.to_s[0] == ?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
يمكن أيضًا تنزيل الشيفرة المصدرية كجزء من مشروع ريلز في GitHub.