diff options
Diffstat (limited to 'activemodel/lib')
-rw-r--r-- | activemodel/lib/active_model/attribute_methods.rb | 127 | ||||
-rw-r--r-- | activemodel/lib/active_model/callbacks.rb | 50 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations.rb | 17 |
3 files changed, 133 insertions, 61 deletions
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 16fcf14009..f30d00b355 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -3,32 +3,32 @@ require 'active_support/core_ext/class/attribute' require 'active_support/deprecation' module ActiveModel + # Raised when an attribute is not defined. class MissingAttributeError < NoMethodError end # == Active Model Attribute Methods # - # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and suffixes - # to your methods as well as handling the creation of Active Record like class methods - # such as +table_name+. + # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and + # suffixes to your methods as well as handling the creation of Active Record + # like class methods such as +table_name+. # # The requirements to implement ActiveModel::AttributeMethods are to: # - # * <tt>include ActiveModel::AttributeMethods</tt> in your object + # * <tt>include ActiveModel::AttributeMethods</tt> in your object. # * Call each Attribute Method module method you want to add, such as - # attribute_method_suffix or attribute_method_prefix - # * Call <tt>define_attribute_methods</tt> after the other methods are - # called. - # * Define the various generic +_attribute+ methods that you have declared + # +attribute_method_suffix+ or +attribute_method_prefix+. + # * Call +define_attribute_methods+ after the other methods are called. + # * Define the various generic +_attribute+ methods that you have declared. # # A minimal implementation could be: # # class Person # include ActiveModel::AttributeMethods # - # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!' + # attribute_method_affix prefix: 'reset_', suffix: '_to_default!' # attribute_method_suffix '_contrived?' # attribute_method_prefix 'clear_' - # define_attribute_methods 'name' + # define_attribute_methods :name # # attr_accessor :name # @@ -43,17 +43,16 @@ module ActiveModel # end # # def reset_attribute_to_default!(attr) - # send("#{attr}=", "Default Name") + # send("#{attr}=", 'Default Name') # end # end # # Note that whenever you include ActiveModel::AttributeMethods in your class, - # it requires you to implement an <tt>attributes</tt> method which returns a hash + # it requires you to implement an +attributes+ method which returns a hash # with each attribute name in your model as hash key and the attribute value as # hash value. # # Hash keys must be strings. - # module AttributeMethods extend ActiveSupport::Concern @@ -79,11 +78,9 @@ module ActiveModel # An instance method <tt>#{prefix}attribute</tt> must exist and accept # at least the +attr+ argument. # - # For example: - # # class Person - # # include ActiveModel::AttributeMethods + # # attr_accessor :name # attribute_method_prefix 'clear_' # define_attribute_methods :name @@ -96,7 +93,7 @@ module ActiveModel # end # # person = Person.new - # person.name = "Bob" + # person.name = 'Bob' # person.name # => "Bob" # person.clear_name # person.name # => nil @@ -114,14 +111,12 @@ module ActiveModel # # attribute#{suffix}(#{attr}, *args, &block) # - # An <tt>attribute#{suffix}</tt> instance method must exist and accept at least - # the +attr+ argument. - # - # For example: + # An <tt>attribute#{suffix}</tt> instance method must exist and accept at + # least the +attr+ argument. # # class Person - # # include ActiveModel::AttributeMethods + # # attr_accessor :name # attribute_method_suffix '_short?' # define_attribute_methods :name @@ -134,7 +129,7 @@ module ActiveModel # end # # person = Person.new - # person.name = "Bob" + # person.name = 'Bob' # person.name # => "Bob" # person.name_short? # => true def attribute_method_suffix(*suffixes) @@ -155,13 +150,11 @@ module ActiveModel # An <tt>#{prefix}attribute#{suffix}</tt> instance method must exist and # accept at least the +attr+ argument. # - # For example: - # # class Person - # # include ActiveModel::AttributeMethods + # # attr_accessor :name - # attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!' + # attribute_method_affix prefix: 'reset_', suffix: '_to_default!' # define_attribute_methods :name # # private @@ -184,14 +177,27 @@ module ActiveModel # Allows you to make aliases for attributes. # # class Person + # include ActiveModel::AttributeMethods + # # attr_accessor :name + # attribute_method_suffix '_short?' + # define_attribute_methods :name + # # alias_attribute :nickname, :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end # end # # person = Person.new - # person.nickname = "Bob" - # person.nickname # => "Bob" - # person.name # => "Bob" + # person.name = 'Bob' + # person.name # => "Bob" + # person.nickname # => "Bob" + # person.name_short? # => true + # person.nickname_short? # => true def alias_attribute(new_name, old_name) self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s) attribute_method_matchers.each do |matcher| @@ -204,13 +210,13 @@ module ActiveModel # Declares the attributes that should be prefixed and suffixed by # ActiveModel::AttributeMethods. # - # To use, pass in an array of attribute names (as strings or symbols), - # be sure to declare +define_attribute_methods+ after you define any - # prefix, suffix or affix methods, or they will not hook in. + # To use, pass attribute names (as strings or symbols), be sure to declare + # +define_attribute_methods+ after you define any prefix, suffix or affix + # methods, or they will not hook in. # # class Person - # # include ActiveModel::AttributeMethods + # # attr_accessor :name, :age, :address # attribute_method_prefix 'clear_' # @@ -229,6 +235,35 @@ module ActiveModel attr_names.flatten.each { |attr_name| define_attribute_method(attr_name) } end + # Declares an attribute that should be prefixed and suffixed by + # ActiveModel::AttributeMethods. + # + # To use, pass an attribute name (as string or symbol), be sure to declare + # +define_attribute_method+ after you define any prefix, suffix or affix + # method, or they will not hook in. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # + # # Call to define_attribute_method must appear after the + # # attribute_method_prefix, attribute_method_suffix or + # # attribute_method_affix declares. + # define_attribute_method :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name # => "Bob" + # person.name_short? # => true def define_attribute_method(attr_name) attribute_method_matchers.each do |matcher| method_name = matcher.method_name(attr_name) @@ -246,7 +281,29 @@ module ActiveModel attribute_method_matchers_cache.clear end - # Removes all the previously dynamically defined methods from the class + # Removes all the previously dynamically defined methods from the class. + # + # class Person + # include ActiveModel::AttributeMethods + # + # attr_accessor :name + # attribute_method_suffix '_short?' + # define_attribute_method :name + # + # private + # + # def attribute_short?(attr) + # send(attr).length < 5 + # end + # end + # + # person = Person.new + # person.name = 'Bob' + # person.name_short? # => true + # + # Person.undefine_attribute_methods + # + # person.name_short? # => NoMethodError def undefine_attribute_methods generated_attribute_methods.module_eval do instance_methods.each { |m| undef_method(m) } diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb index ebb4b51aa3..b8ba1a0a52 100644 --- a/activemodel/lib/active_model/callbacks.rb +++ b/activemodel/lib/active_model/callbacks.rb @@ -6,7 +6,7 @@ module ActiveModel # Provides an interface for any class to have Active Record like callbacks. # # Like the Active Record methods, the callback chain is aborted as soon as - # one of the methods in the chain returns false. + # one of the methods in the chain returns +false+. # # First, extend ActiveModel::Callbacks from the class you are creating: # @@ -18,9 +18,10 @@ module ActiveModel # # define_model_callbacks :create, :update # - # This will provide all three standard callbacks (before, around and after) for - # both the :create and :update methods. To implement, you need to wrap the methods - # you want callbacks on in a block so that the callbacks get a chance to fire: + # This will provide all three standard callbacks (before, around and after) + # for both the <tt>:create</tt> and <tt>:update</tt> methods. To implement, + # you need to wrap the methods you want callbacks on in a block so that the + # callbacks get a chance to fire: # # def create # run_callbacks :create do @@ -28,8 +29,8 @@ module ActiveModel # end # end # - # Then in your class, you can use the +before_create+, +after_create+ and +around_create+ - # methods, just as you would in an Active Record module. + # Then in your class, you can use the +before_create+, +after_create+ and + # +around_create+ methods, just as you would in an Active Record module. # # before_create :action_before_create # @@ -38,12 +39,12 @@ module ActiveModel # end # # You can choose not to have all three callbacks by passing a hash to the - # define_model_callbacks method. + # +define_model_callbacks+ method. # - # define_model_callbacks :create, :only => [:after, :before] + # define_model_callbacks :create, only: [:after, :before] # - # Would only create the after_create and before_create callback methods in your - # class. + # Would only create the +after_create+ and +before_create+ callback methods in + # your class. module Callbacks def self.extended(base) base.class_eval do @@ -51,25 +52,27 @@ module ActiveModel end end - # define_model_callbacks accepts the same options define_callbacks does, in case - # you want to overwrite a default. Besides that, it also accepts an :only option, - # where you can choose if you want all types (before, around or after) or just some. + # define_model_callbacks accepts the same options +define_callbacks+ does, + # in case you want to overwrite a default. Besides that, it also accepts an + # <tt>:only</tt> option, where you can choose if you want all types (before, + # around or after) or just some. # - # define_model_callbacks :initializer, :only => :after + # define_model_callbacks :initializer, only: :after # - # Note, the <tt>:only => <type></tt> hash will apply to all callbacks defined on - # that method call. To get around this you can call the define_model_callbacks + # Note, the <tt>only: <type></tt> hash will apply to all callbacks defined + # on that method call. To get around this you can call the define_model_callbacks # method as many times as you need. # - # define_model_callbacks :create, :only => :after - # define_model_callbacks :update, :only => :before - # define_model_callbacks :destroy, :only => :around + # define_model_callbacks :create, only: :after + # define_model_callbacks :update, only: :before + # define_model_callbacks :destroy, only: :around # - # Would create +after_create+, +before_update+ and +around_destroy+ methods only. + # Would create +after_create+, +before_update+ and +around_destroy+ methods + # only. # - # You can pass in a class to before_<type>, after_<type> and around_<type>, in which - # case the callback will call that class's <action>_<type> method passing the object - # that the callback is being called on. + # You can pass in a class to before_<type>, after_<type> and around_<type>, + # in which case the callback will call that class's <action>_<type> method + # passing the object that the callback is being called on. # # class MyModel # extend ActiveModel::Callbacks @@ -83,7 +86,6 @@ module ActiveModel # # obj is the MyModel instance that the callback is being called on # end # end - # def define_model_callbacks(*callbacks) options = callbacks.extract_options! options = { diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 06eebf79d9..cd596e37d2 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -38,7 +38,6 @@ module ActiveModel # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+ method # to your instances initialized with a new <tt>ActiveModel::Errors</tt> object, so # there is no need for you to do this manually. - # module Validations extend ActiveSupport::Concern @@ -153,6 +152,21 @@ module ActiveModel # List all validators that are being used to validate the model using # +validates_with+ method. + # + # class Person + # include ActiveModel::Validations + # + # validates_with MyValidator + # validates_with OtherValidator, on: :create + # validates_with StrictValidator, strict: true + # end + # + # Person.validators + # # => [ + # # #<MyValidator:0x007fbff403e808 @options={}>, + # # #<OtherValidator:0x007fbff403d930 @options={:on=>:create}>, + # # #<StrictValidator:0x007fbff3204a30 @options={:strict=>true}> + # # ] def validators _validators.values.flatten.uniq end @@ -221,7 +235,6 @@ module ActiveModel # @data[key] # end # end - # alias :read_attribute_for_validation :send protected |