diff options
Diffstat (limited to 'activemodel/README.rdoc')
-rw-r--r-- | activemodel/README.rdoc | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc new file mode 100644 index 0000000000..f6beff14e1 --- /dev/null +++ b/activemodel/README.rdoc @@ -0,0 +1,272 @@ += Active Model -- model interfaces for Rails + +Active Model provides a known set of interfaces for usage in model classes. +They allow for Action Pack helpers to interact with non-Active Record models, +for example. Active Model also helps with building custom ORMs for use outside of +the Rails framework. + +Prior to Rails 3.0, if a plugin or gem developer wanted to have an object +interact with Action Pack helpers, it was required to either copy chunks of +code from Rails, or monkey patch entire helpers to make them handle objects +that did not exactly conform to the Active Record interface. This would result +in code duplication and fragile applications that broke on upgrades. Active +Model solves this by defining an explicit API. You can read more about the +API in <tt>ActiveModel::Lint::Tests</tt>. + +Active Model provides a default module that implements the basic API required +to integrate with Action Pack out of the box: <tt>ActiveModel::Model</tt>. + + 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 + +It includes model name introspections, conversions, translations and +validations, resulting in a class suitable to be used with Action Pack. +See <tt>ActiveModel::Model</tt> for more examples. + +Active Model also provides the following functionality to have ORM-like +behavior out of the box: + +* Add attribute magic to objects + + 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 + + {Learn more}[link:classes/ActiveModel/AttributeMethods.html] + +* Callbacks for certain operations + + class Person + extend ActiveModel::Callbacks + define_model_callbacks :create + + def create + run_callbacks :create do + # Your create action methods here + end + end + end + + This generates +before_create+, +around_create+ and +after_create+ + class methods that wrap your create method. + + {Learn more}[link:classes/ActiveModel/Callbacks.html] + +* Tracking value changes + + 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']} + + {Learn more}[link:classes/ActiveModel/Dirty.html] + +* Adding +errors+ interface to objects + + Exposing error messages allows objects to interact with Action Pack + helpers seamlessly. + + 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"] + + {Learn more}[link:classes/ActiveModel/Errors.html] + +* Model name introspection + + class NamedPerson + extend ActiveModel::Naming + end + + NamedPerson.model_name.name # => "NamedPerson" + NamedPerson.model_name.human # => "Named person" + + {Learn more}[link:classes/ActiveModel/Naming.html] + +* Making objects serializable + + ActiveModel::Serialization provides a standard interface for your object + to provide +to_json+ or +to_xml+ serialization. + + 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 SerialPerson + include ActiveModel::Serializers::Xml + end + + s = SerialPerson.new + s.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person... + + {Learn more}[link:classes/ActiveModel/Serialization.html] + +* Internationalization (i18n) support + + class Person + extend ActiveModel::Translation + end + + Person.human_attribute_name('my_attribute') + # => "My attribute" + + {Learn more}[link:classes/ActiveModel/Translation.html] + +* Validation support + + 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 + + {Learn more}[link:classes/ActiveModel/Validations.html] + +* Custom validators + + class HasNameValidator < ActiveModel::Validator + def validate(record) + record.errors[: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 + + {Learn more}[link:classes/ActiveModel/Validator.html] + + +== Download and installation + +The latest version of Active Model can be installed with RubyGems: + + % [sudo] gem install activemodel + +Source code can be downloaded as part of the Rails project on GitHub + +* https://github.com/rails/rails/tree/master/activemodel + + +== License + +Active Model is released under the MIT license: + +* http://www.opensource.org/licenses/MIT + + +== Support + +API documentation is at + +* http://api.rubyonrails.org + +Bug reports can be filed for the Ruby on Rails project here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core + |