From cb9d03f0d46b17986894a3aadaad6eaa55dc66b3 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Sat, 3 Mar 2012 04:19:39 -0300 Subject: [PATCH] Add docs with usage examples for ActiveModel::Model Also add test to ensure basic model does not explode when initialized with nil. --- activemodel/README.rdoc | 19 +++++++++ activemodel/lib/active_model/model.rb | 56 ++++++++++++++++++++++++++- activemodel/test/cases/model_test.rb | 7 ++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index a7ba27ba73..9b121510a9 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -13,6 +13,25 @@ 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 ActiveModel::Lint::Tests. +Active Model provides a default module that implements the basic API required +to integrate with Action Pack out of the box: +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? # => false + +It includes model name instrospection, conversions, translations and +validations, resulting in a class suitable to be used with ActionPack. +See +ActiveModel::Model+ for more examples. + Active Model also provides the following functionality to have ORM-like behavior out of the box: diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb index 9228d54015..811332163b 100644 --- a/activemodel/lib/active_model/model.rb +++ b/activemodel/lib/active_model/model.rb @@ -1,4 +1,58 @@ module ActiveModel + + # == Active Model Basic Model + # + # Includes the required interface for an object to interact with +ActionPack+, + # using different +ActiveModel+ modules. It includes model name instrospection, + # conversions, translations and validations . Besides that, it allows you to + # initialize the object with a hash of attributes, pretty much like + # +ActiveRecord+ does. + # + # A minimal implementation could be: + # + # class Person + # include ActiveModel::Model + # attr_accessor :name, :age + # end + # + # person = Person.new(:name => 'bob', :age => '18') + # person.name # => 'bob' + # person.age # => 18 + # + # Note that, by default, +ActiveModel::Model+ implements +persisted?+ to + # return +false+, which is the most common case. You may want to override it + # in your class to simulate a different scenario: + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name + # + # def persisted? + # self.id == 1 + # end + # end + # + # person = Person.new(:id => 1, :name => 'bob') + # person.persisted? # => true + # + # Also, if for some reason you need to run code on +initialize+, make sure you + # call super if you want the attributes hash initialization to happen. + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name, :omg + # + # def initialize(attributes) + # super + # @omg ||= true + # end + # end + # + # person = Person.new(:id => 1, :name => 'bob') + # person.omg # => true + # + # For more detailed information on other functionality available, please refer + # to the specific modules included in +ActiveModel::Model+ (see below). module Model def self.included(base) base.class_eval do @@ -11,7 +65,7 @@ module ActiveModel def initialize(params={}) params.each do |attr, value| - self.send(:"#{attr}=", value) + self.send("#{attr}=", value) end if params end diff --git a/activemodel/test/cases/model_test.rb b/activemodel/test/cases/model_test.rb index d3e00b044f..d93fd96b88 100644 --- a/activemodel/test/cases/model_test.rb +++ b/activemodel/test/cases/model_test.rb @@ -16,4 +16,11 @@ class ModelTest < ActiveModel::TestCase object = BasicModel.new(:attr => "value") assert_equal object.attr, "value" end + + def test_initialize_with_nil_or_empty_hash_params_does_not_explode + assert_nothing_raised do + BasicModel.new() + BasicModel.new({}) + end + end end