aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib
diff options
context:
space:
mode:
authorGonçalo Silva <goncalossilva@gmail.com>2010-08-10 18:15:12 +0100
committerGonçalo Silva <goncalossilva@gmail.com>2010-08-10 18:15:12 +0100
commit62658500049fbb7a5e7d75537dd6f6a374204207 (patch)
tree8892d8305ced43866068a6c1c66548e465e45b38 /activemodel/lib
parentcd2bbed9846d84a1230a1b9e52843eedca17b28d (diff)
parente86cced311539932420f9cda49d736606d106c28 (diff)
downloadrails-62658500049fbb7a5e7d75537dd6f6a374204207.tar.gz
rails-62658500049fbb7a5e7d75537dd6f6a374204207.tar.bz2
rails-62658500049fbb7a5e7d75537dd6f6a374204207.zip
Merge branch 'master' of http://github.com/rails/rails
Diffstat (limited to 'activemodel/lib')
-rw-r--r--activemodel/lib/active_model/attribute_methods.rb2
-rw-r--r--activemodel/lib/active_model/callbacks.rb2
-rw-r--r--activemodel/lib/active_model/conversion.rb6
-rw-r--r--activemodel/lib/active_model/dirty.rb12
-rw-r--r--activemodel/lib/active_model/errors.rb34
-rw-r--r--activemodel/lib/active_model/mass_assignment_security/permission_set.rb3
-rw-r--r--activemodel/lib/active_model/naming.rb38
-rw-r--r--activemodel/lib/active_model/serialization.rb2
-rw-r--r--activemodel/lib/active_model/serializers/json.rb18
-rw-r--r--activemodel/lib/active_model/translation.rb2
-rw-r--r--activemodel/lib/active_model/validations.rb24
-rw-r--r--activemodel/lib/active_model/validations/length.rb11
-rw-r--r--activemodel/lib/active_model/validations/validates.rb2
-rw-r--r--activemodel/lib/active_model/validator.rb6
-rw-r--r--activemodel/lib/active_model/version.rb2
15 files changed, 97 insertions, 67 deletions
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index 817640b178..a43436e008 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -283,7 +283,7 @@ module ActiveModel
@attribute_methods_generated = true
end
- # Removes all the preiously dynamically defined methods from the class
+ # Removes all the previously dynamically defined methods from the class
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 e7aad17021..8c10c54b54 100644
--- a/activemodel/lib/active_model/callbacks.rb
+++ b/activemodel/lib/active_model/callbacks.rb
@@ -19,7 +19,7 @@ module ActiveModel
#
# define_model_callbacks :create, :update
#
- # This will provide all three standard callbacks (before, around and after) around
+ # 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:
#
diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb
index 2a1650faa9..d2bd160dc7 100644
--- a/activemodel/lib/active_model/conversion.rb
+++ b/activemodel/lib/active_model/conversion.rb
@@ -17,9 +17,9 @@ module ActiveModel
# end
#
# cm = ContactMessage.new
- # cm.to_model == self #=> true
- # cm.to_key #=> nil
- # cm.to_param #=> nil
+ # cm.to_model == self # => true
+ # cm.to_key # => nil
+ # cm.to_param # => nil
#
module Conversion
# If your object is already designed to implement all of the Active Model
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index 4c80863e3a..2516377afd 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -37,12 +37,13 @@ module ActiveModel
# end
#
# def name=(val)
- # name_will_change!
+ # name_will_change! unless val == @name
# @name = val
# end
#
# def save
# @previously_changed = changes
+ # @changed_attributes.clear
# end
#
# end
@@ -77,13 +78,10 @@ module ActiveModel
# person.changed # => ['name']
# person.changes # => { 'name' => ['Bill', 'Bob'] }
#
- # Resetting an attribute returns it to its original state:
- # person.reset_name! # => 'Bill'
- # person.changed? # => false
- # person.name_changed? # => false
- # person.name # => 'Bill'
+ # 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.
#
- # Before modifying an attribute in-place:
# person.name_will_change!
# person.name << 'y'
# person.name_change # => ['Bill', 'Billy']
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 482b3dac47..272ddb1554 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -37,11 +37,11 @@ module ActiveModel
# send(attr)
# end
#
- # def ErrorsPerson.human_attribute_name(attr, options = {})
+ # def Person.human_attribute_name(attr, options = {})
# attr
# end
#
- # def ErrorsPerson.lookup_ancestors
+ # def Person.lookup_ancestors
# [self]
# end
#
@@ -83,20 +83,16 @@ module ActiveModel
# When passed a symbol or a name of a method, returns an array of errors
# for the method.
#
- # p.errors[:name] #=> ["can not be nil"]
- # p.errors['name'] #=> ["can not be nil"]
+ # p.errors[:name] # => ["can not be nil"]
+ # p.errors['name'] # => ["can not be nil"]
def [](attribute)
- if errors = get(attribute.to_sym)
- errors
- else
- set(attribute.to_sym, [])
- end
+ get(attribute.to_sym) || set(attribute.to_sym, [])
end
# Adds to the supplied attribute the supplied error message.
#
# p.errors[:name] = "must be set"
- # p.errors[:name] #=> ['must be set']
+ # p.errors[:name] # => ['must be set']
def []=(attribute, error)
self[attribute.to_sym] << error
end
@@ -124,9 +120,9 @@ module ActiveModel
# Returns the number of error messages.
#
# p.errors.add(:name, "can't be blank")
- # p.errors.size #=> 1
+ # p.errors.size # => 1
# p.errors.add(:name, "must be specified")
- # p.errors.size #=> 2
+ # p.errors.size # => 2
def size
values.flatten.size
end
@@ -135,16 +131,16 @@ module ActiveModel
#
# p.errors.add(:name, "can't be blank")
# p.errors.add(:name, "must be specified")
- # p.errors.to_a #=> ["name can't be blank", "name must be specified"]
+ # p.errors.to_a # => ["name can't be blank", "name must be specified"]
def to_a
full_messages
end
# Returns the number of error messages.
# p.errors.add(:name, "can't be blank")
- # p.errors.count #=> 1
+ # p.errors.count # => 1
# p.errors.add(:name, "must be specified")
- # p.errors.count #=> 2
+ # p.errors.count # => 2
def count
to_a.size
end
@@ -158,8 +154,8 @@ module ActiveModel
#
# p.errors.add(:name, "can't be blank")
# p.errors.add(:name, "must be specified")
- # p.errors.to_xml #=> Produces:
- #
+ # p.errors.to_xml
+ # # =>
# # <?xml version=\"1.0\" encoding=\"UTF-8\"?>
# # <errors>
# # <error>name can't be blank</error>
@@ -169,9 +165,9 @@ module ActiveModel
to_a.to_xml options.reverse_merge(:root => "errors", :skip_types => true)
end
- # Returns an array as JSON representation for this object.
+ # Returns an ActiveSupport::OrderedHash that can be used as the JSON representation for this object.
def as_json(options=nil)
- to_a
+ self
end
# Adds +message+ to the error messages on +attribute+, which will be returned on a call to
diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
index 7c48472799..9fcb94d48a 100644
--- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
+++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
@@ -1,3 +1,4 @@
+require 'set'
require 'active_model/mass_assignment_security/sanitizer'
module ActiveModel
@@ -36,4 +37,4 @@ module ActiveModel
end
end
end
-end \ No newline at end of file
+end
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb
index ca1e9f0ee8..b74d669f0a 100644
--- a/activemodel/lib/active_model/naming.rb
+++ b/activemodel/lib/active_model/naming.rb
@@ -17,7 +17,10 @@ module ActiveModel
end
# Transform the model name into a more humane format, using I18n. By default,
- # it will underscore then humanize the class name (BlogPost.model_name.human #=> "Blog post").
+ # it will underscore then humanize the class name
+ #
+ # BlogPost.model_name.human # => "Blog post"
+ #
# Specify +options+ with additional translating options.
def human(options={})
return @human unless @klass.respond_to?(:lookup_ancestors) &&
@@ -45,8 +48,8 @@ module ActiveModel
# extend ActiveModel::Naming
# end
#
- # BookCover.model_name #=> "BookCover"
- # BookCover.model_name.human #=> "Book cover"
+ # BookCover.model_name # => "BookCover"
+ # BookCover.model_name.human # => "Book cover"
#
# Providing the functionality that ActiveModel::Naming provides in your object
# is required to pass the Active Model Lint test. So either extending the provided
@@ -57,6 +60,35 @@ module ActiveModel
def model_name
@_model_name ||= ActiveModel::Name.new(self)
end
+
+ # Returns the plural class name of a record or class. Examples:
+ #
+ # ActiveModel::Naming.plural(post) # => "posts"
+ # ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people"
+ def self.plural(record_or_class)
+ model_name_from_record_or_class(record_or_class).plural
+ end
+
+ # Returns the singular class name of a record or class. Examples:
+ #
+ # ActiveModel::Naming.singular(post) # => "post"
+ # ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person"
+ def self.singular(record_or_class)
+ model_name_from_record_or_class(record_or_class).singular
+ end
+
+ # Identifies whether the class name of a record or class is uncountable. Examples:
+ #
+ # ActiveModel::Naming.uncountable?(Sheep) # => true
+ # ActiveModel::Naming.uncountable?(Post) => false
+ def self.uncountable?(record_or_class)
+ plural(record_or_class) == singular(record_or_class)
+ end
+
+ private
+ def self.model_name_from_record_or_class(record_or_class)
+ (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name
+ end
end
end
diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb
index 5670ec74cb..e675937f4d 100644
--- a/activemodel/lib/active_model/serialization.rb
+++ b/activemodel/lib/active_model/serialization.rb
@@ -61,6 +61,8 @@ module ActiveModel
# person.serializable_hash # => {"name"=>"Bob"}
# person.to_json # => "{\"name\":\"Bob\"}"
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
+ #
+ # Valid options are <tt>:only</tt>, <tt>:except</tt> and <tt>:methods</tt> .
module Serialization
def serializable_hash(options = nil)
options ||= {}
diff --git a/activemodel/lib/active_model/serializers/json.rb b/activemodel/lib/active_model/serializers/json.rb
index 918cd0ab76..e1dbc522de 100644
--- a/activemodel/lib/active_model/serializers/json.rb
+++ b/activemodel/lib/active_model/serializers/json.rb
@@ -19,8 +19,8 @@ module ActiveModel
# passed through +options+.
#
# The option <tt>ActiveModel::Base.include_root_in_json</tt> controls the
- # top-level behavior of to_json. It is true by default. When it is <tt>true</tt>,
- # to_json will emit a single root node named after the object's type. For example:
+ # top-level behavior of +to_json+. If true (the default) +to_json+ will
+ # emit a single root node named after the object's type. For example:
#
# konata = User.find(1)
# konata.to_json
@@ -32,11 +32,11 @@ module ActiveModel
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true}
#
- # The remainder of the examples in this section assume include_root_in_json is set to
- # <tt>false</tt>.
+ # The remainder of the examples in this section assume +include_root_in_json+
+ # is false.
#
- # Without any +options+, the returned JSON string will include all
- # the model's attributes. For example:
+ # Without any +options+, the returned JSON string will include all the model's
+ # attributes. For example:
#
# konata = User.find(1)
# konata.to_json
@@ -52,14 +52,14 @@ module ActiveModel
# konata.to_json(:except => [ :id, :created_at, :age ])
# # => {"name": "Konata Izumi", "awesome": true}
#
- # To include any methods on the model, use <tt>:methods</tt>.
+ # To include the result of some method calls on the model use <tt>:methods</tt>:
#
# konata.to_json(:methods => :permalink)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
# "created_at": "2006/08/01", "awesome": true,
# "permalink": "1-konata-izumi"}
#
- # To include associations, use <tt>:include</tt>.
+ # To include associations use <tt>:include</tt>:
#
# konata.to_json(:include => :posts)
# # => {"id": 1, "name": "Konata Izumi", "age": 16,
@@ -67,7 +67,7 @@ module ActiveModel
# "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
# {"id": 2, author_id: 1, "title": "So I was thinking"}]}
#
- # 2nd level and higher order associations work as well:
+ # Second level and higher order associations work as well:
#
# konata.to_json(:include => { :posts => {
# :include => { :comments => {
diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb
index 0554677296..0facbd6ce1 100644
--- a/activemodel/lib/active_model/translation.rb
+++ b/activemodel/lib/active_model/translation.rb
@@ -14,7 +14,7 @@ module ActiveModel
# end
#
# TranslatedPerson.human_attribute_name('my_attribute')
- # #=> "My attribute"
+ # # => "My attribute"
#
# This also provides the required class methods for hooking into the
# Rails internationalization API, including being able to define a
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 5779ba3b29..3407c59e7a 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -24,20 +24,16 @@ module ActiveModel
# end
#
# Which provides you with the full standard validation stack that you
- # know from ActiveRecord.
+ # know from Active Record:
#
# person = Person.new
- # person.valid?
- # #=> true
- # person.invalid?
- # #=> false
+ # person.valid? # => true
+ # person.invalid? # => false
+ #
# person.first_name = 'zoolander'
- # person.valid?
- # #=> false
- # person.invalid?
- # #=> true
- # person.errors
- # #=> #<OrderedHash {:first_name=>["starts with z."]}>
+ # person.valid? # => false
+ # person.invalid? # => true
+ # person.errors # => #<OrderedHash {:first_name=>["starts with z."]}>
#
# Note that ActiveModel::Validations automatically adds an +errors+ method
# to your instances initialized with a new ActiveModel::Errors object, so
@@ -122,11 +118,13 @@ module ActiveModel
# end
#
def validate(*args, &block)
- options = args.last
- if options.is_a?(Hash) && options.key?(:on)
+ options = args.extract_options!
+ if options.key?(:on)
+ options = options.dup
options[:if] = Array.wrap(options[:if])
options[:if] << "validation_context == :#{options[:on]}"
end
+ args << options
set_callback(:validate, *args, &block)
end
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb
index c8a77ad666..a7af4f2b4d 100644
--- a/activemodel/lib/active_model/validations/length.rb
+++ b/activemodel/lib/active_model/validations/length.rb
@@ -40,8 +40,6 @@ module ActiveModel
CHECKS.each do |key, validity_check|
next unless check_value = options[key]
- default_message = options[MESSAGES[key]]
- options[:message] ||= default_message if default_message
valid_value = if key == :maximum
value.nil? || value.size.send(validity_check, check_value)
@@ -51,8 +49,13 @@ module ActiveModel
next if valid_value
- record.errors.add(attribute, MESSAGES[key],
- options.except(*RESERVED_OPTIONS).merge!(:count => check_value))
+ errors_options = options.except(*RESERVED_OPTIONS)
+ errors_options[:count] = check_value
+
+ default_message = options[MESSAGES[key]]
+ errors_options[:message] ||= default_message if default_message
+
+ record.errors.add(attribute, MESSAGES[key], errors_options)
end
end
end
diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb
index 0674640925..3260e6bc5a 100644
--- a/activemodel/lib/active_model/validations/validates.rb
+++ b/activemodel/lib/active_model/validations/validates.rb
@@ -40,7 +40,7 @@ module ActiveModel
# validates :email, :presence => true, :email => true
# end
#
- # Validator classes my also exist within the class being validated
+ # Validator classes may also exist within the class being validated
# allowing custom modules of validators to be included as needed e.g.
#
# class Film
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb
index 689c617177..163124d531 100644
--- a/activemodel/lib/active_model/validator.rb
+++ b/activemodel/lib/active_model/validator.rb
@@ -102,8 +102,8 @@ module ActiveModel #:nodoc:
#
# == Examples
#
- # PresenceValidator.kind #=> :presence
- # UniquenessValidator.kind #=> :uniqueness
+ # PresenceValidator.kind # => :presence
+ # UniquenessValidator.kind # => :uniqueness
#
def self.kind
@kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous?
@@ -111,7 +111,7 @@ module ActiveModel #:nodoc:
# Accepts options that will be made available through the +options+ reader.
def initialize(options)
- @options = options
+ @options = options.freeze
end
# Return the kind for this validator.
diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb
index c36fc8b1f7..f2f4b15520 100644
--- a/activemodel/lib/active_model/version.rb
+++ b/activemodel/lib/active_model/version.rb
@@ -3,7 +3,7 @@ module ActiveModel
MAJOR = 3
MINOR = 0
TINY = 0
- BUILD = "beta4"
+ BUILD = "rc"
STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
end