diff options
Diffstat (limited to 'activemodel/lib/active_model')
| -rw-r--r-- | activemodel/lib/active_model/dirty.rb | 31 | ||||
| -rw-r--r-- | activemodel/lib/active_model/naming.rb | 7 | ||||
| -rw-r--r-- | activemodel/lib/active_model/secure_password.rb | 2 | ||||
| -rw-r--r-- | activemodel/lib/active_model/validations/numericality.rb | 14 |
4 files changed, 47 insertions, 7 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 98ffffeb10..dc6088a39a 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -17,6 +17,7 @@ module ActiveModel # * Call <tt>changes_applied</tt> after the changes are persisted. # * Call <tt>reset_changes</tt> when you want to reset the changes # information. + # * Call <tt>undo_changes</tt> when you want to restore previous data. # # A minimal implementation could be: # @@ -42,6 +43,10 @@ module ActiveModel # def reload! # reset_changes # end + # + # def rollback! + # undo_changes + # end # end # # A newly instantiated object is unchanged: @@ -72,6 +77,13 @@ module ActiveModel # person.reload! # person.previous_changes # => {} # + # Rollback the changes: + # + # person.name = "Uncle Bob" + # person.rollback! + # person.name # => "Bill" + # person.name_changed? # => false + # # Assigning the same value leaves the attribute unchanged: # # person.name = 'Bill' @@ -84,9 +96,11 @@ module ActiveModel # person.changed # => ["name"] # person.changes # => {"name" => ["Bill", "Bob"]} # - # If an attribute is modified in-place then make use of <tt>[attribute_name]_will_change!</tt> - # to mark that the attribute is changing. Otherwise ActiveModel can't track - # changes to in-place attributes. + # If an attribute is modified in-place then make use of + # +[attribute_name]_will_change!+ to mark that the attribute is changing. + # Otherwise Active Model can't track changes to in-place attributes. Note + # that Active Record can detect in-place modifications automatically. You do + # not need to call +[attribute_name]_will_change!+ on Active Record models. # # person.name_will_change! # person.name_change # => ["Bill", "Bill"] @@ -165,17 +179,22 @@ module ActiveModel private # Removes current changes and makes them accessible through +previous_changes+. - def changes_applied + def changes_applied # :doc: @previously_changed = changes @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new end - # Removes all dirty data: current changes and previous changes - def reset_changes + # Removes all dirty data: current changes and previous changes. + def reset_changes # :doc: @previously_changed = ActiveSupport::HashWithIndifferentAccess.new @changed_attributes = ActiveSupport::HashWithIndifferentAccess.new end + # Restore all previous data. + def undo_changes # :doc: + changed_attributes.each_key { |attr| reset_attribute! attr } + end + # Handle <tt>*_change</tt> for +method_missing+. def attribute_change(attr) [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr) diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index 5219de2606..86f5c96af9 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -214,6 +214,13 @@ module ActiveModel # is required to pass the Active Model Lint test. So either extending the # provided method below, or rolling your own is required. module Naming + def self.extended(base) #:nodoc: + base.class_eval do + remove_possible_method(:model_name) + delegate :model_name, to: :class + end + end + # Returns an ActiveModel::Name object for module. It can be # used to retrieve all kinds of naming-related information # (See ActiveModel::Name for more information). diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index fdfd8cb147..7e179cf4b7 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -64,6 +64,8 @@ module ActiveModel include InstanceMethodsOnActivation if options.fetch(:validations, true) + include ActiveModel::Validations + # This ensures the model has a password by checking whether the password_digest # is present, so that this works with both new and existing records. However, # when there is an error, the message is added to the password attribute instead diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb index a9fb9804d4..5bd162433d 100644 --- a/activemodel/lib/active_model/validations/numericality.rb +++ b/activemodel/lib/active_model/validations/numericality.rb @@ -30,7 +30,7 @@ module ActiveModel return end - if options[:only_integer] + if allow_only_integer?(record) unless value = parse_raw_value_as_an_integer(raw_value) record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value)) return @@ -75,6 +75,17 @@ module ActiveModel filtered[:value] = value filtered end + + def allow_only_integer?(record) + case options[:only_integer] + when Symbol + record.send(options[:only_integer]) + when Proc + options[:only_integer].call(record) + else + options[:only_integer] + end + end end module HelperMethods @@ -121,6 +132,7 @@ module ActiveModel # * <tt>:equal_to</tt> # * <tt>:less_than</tt> # * <tt>:less_than_or_equal_to</tt> + # * <tt>:only_integer</tt> # # For example: # |
