1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

important revision in (current) chapter 3 of validations guide

This commit is contained in:
Xavier Noria 2009-03-08 22:23:08 +01:00
parent 2bf922d056
commit 04042ce01e

View file

@ -90,7 +90,7 @@ Note that +save+ also has the ability to skip validations if passed +false+ as a
* +save(false)+
h4. +Object#valid?+ and +Object#invalid?+
h4. +valid?+ and +invalid?+
To verify whether or not an object is valid, Rails uses the +valid?+ method. You can also use this method on your own. +valid?+ triggers your validations and returns true if no errors were added to the object, and false otherwise.
@ -137,11 +137,11 @@ end
=> ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
</ruby>
+Object#invalid?+ is simply the inverse of +Object#valid?+. +invalid?+ triggers your validations and returns true if any errors were added to the object, and false otherwise.
+invalid?+ is simply the inverse of +valid?+. +invalid?+ triggers your validations and returns true if any errors were added to the object, and false otherwise.
h3. +errors.invalid?+
h4. +errors.invalid?+
To verify whether or not a particular attribute of an object is valid, you can use the +errors.invalid?+ method. This method is only useful _after_ validations have been run, because it only inspects the errors collection and does not trigger validations itself. It's different from the +valid?+ method because it doesn't verify the validity of the object as a whole, but only if there are errors found on an individual attribute of the object.
To verify whether or not a particular attribute of an object is valid, you can use the +errors.invalid?+ method. This method is only useful _after_ validations have been run, because it only inspects the errors collection and does not trigger validations itself. It's different from the +ActiveRecord::Base#invalid?+ method explained above because it doesn't verify the validity of the object as a whole, but only if there are errors found on an individual attribute of the object.
<ruby>
class Person < ActiveRecord::Base
@ -156,15 +156,15 @@ We'll cover validation errors in greater depth in the "Working with Validation E
h3. Validation Helpers
Active Record offers many pre-defined validation helpers that you can use directly inside your class definitions. These helpers create validation rules that are commonly used. Every time a validation fails, an error message is added to the object's +errors+ collection, and this message is associated with the field being validated.
Active Record offers many pre-defined validation helpers that you can use directly inside your class definitions. These helpers provide common validation rules. Every time a validation fails, an error message is added to the object's +errors+ collection, and this message is associated with the field being validated.
Each helper accepts an arbitrary number of attributes identified by symbols, so with a single line of code you can add the same kind of validation to several attributes.
Each helper accepts an arbitrary number of attribute names, so with a single line of code you can add the same kind of validation to several attributes.
All these helpers accept the +:on+ and +:message+ options, which define when the validation should be applied and what message should be added to the +errors+ collection when it fails, respectively. The +:on+ option takes one of the values +:save+ (the default), +:create+ or +:update+. There is a default error message for each one of the validation helpers. These messages are used when the +:message+ option isn't used. Let's take a look at each one of the available helpers.
All of them accept the +:on+ and +:message+ options, which define when the validation should be run and what message should be added to the +errors+ collection if it fails, respectively. The +:on+ option takes one of the values +:save+ (the default), +:create+ or +:update+. There is a default error message for each one of the validation helpers. These messages are used when the +:message+ option isn't specified. Let's take a look at each one of the available helpers.
h4. validates_acceptance_of
h4. +validates_acceptance_of+
Validates that a checkbox on the user interface was checked when a form was submitted. This is normally used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and actually this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
Validates that a checkbox on the user interface was checked when a form was submitted. This is typically used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and actually this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
<ruby>
class Person < ActiveRecord::Base
@ -172,7 +172,7 @@ class Person < ActiveRecord::Base
end
</ruby>
The default error message for +validates_acceptance_of+ is "_must be accepted_"
The default error message for +validates_acceptance_of+ is "_must be accepted_".
+validates_acceptance_of+ can receive an +:accept+ option, which determines the value that will be considered acceptance. It defaults to "1", but you can change this.
@ -182,7 +182,7 @@ class Person < ActiveRecord::Base
end
</ruby>
h4. validates_associated
h4. +validates_associated+
You should use this helper when your model has associations with other models and they also need to be validated. When you try to save your object, +valid?+ will be called upon each one of the associated objects.
@ -195,13 +195,13 @@ end
This validation will work with all the association types.
CAUTION: Don't use +validates_associated+ on both ends of your associations, because this will lead to several recursive calls and blow up the method calls' stack.
CAUTION: Don't use +validates_associated+ on both ends of your associations, they would call each other in an infinite loop.
The default error message for +validates_associated+ is "_is invalid_". Note that each associated object will contain its own +errors+ collection; errors do not bubble up to the calling model.
h4. validates_confirmation_of
h4. +validates_confirmation_of+
You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute, using the name of the field that has to be confirmed with '_confirmation' appended.
You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
<ruby>
class Person < ActiveRecord::Base
@ -216,7 +216,7 @@ In your view template you could use something like
<%= text_field :person, :email_confirmation %>
</erb>
NOTE: This check is performed only if +email_confirmation+ is not nil, and by default only on save. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +validates_presence_of+ later on this guide):
This check is performed only if +email_confirmation+ is not +nil+. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +validates_presence_of+ later on this guide):
<ruby>
class Person < ActiveRecord::Base
@ -225,37 +225,37 @@ class Person < ActiveRecord::Base
end
</ruby>
The default error message for +validates_confirmation_of+ is "_doesn't match confirmation_"
The default error message for +validates_confirmation_of+ is "_doesn't match confirmation_".
h4. validates_exclusion_of
h4. +validates_exclusion_of+
This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.
<ruby>
class MovieFile < ActiveRecord::Base
validates_exclusion_of :format, :in => %w(mov avi),
:message => "Extension %s is not allowed"
class Account < ActiveRecord::Base
validates_exclusion_of :subdomain, :in => %w(www),
:message => "Subdomain %s is reserved."
end
</ruby>
The +validates_exclusion_of+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can personalize it with the current attribute's value, through the +%s+ format mask.
The +validates_exclusion_of+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value using the +%s+ format specification.
The default error message for +validates_exclusion_of+ is "_is not included in the list_".
h4. validates_format_of
h4. +validates_format_of+
This helper validates the attributes' values by testing whether they match a given pattern. This pattern must be specified using a Ruby regular expression, which is specified using the +:with+ option.
This helper validates the attributes' values by testing whether they match a given regular expresion, which is specified using the +:with+ option.
<ruby>
class Product < ActiveRecord::Base
validates_format_of :description, :with => /^[a-zA-Z]+$/,
validates_format_of :legacy_code, :with => /\A[a-zA-Z]+\z/,
:message => "Only letters allowed"
end
</ruby>
The default error message for +validates_format_of+ is "_is invalid_".
h4. validates_inclusion_of
h4. +validates_inclusion_of+
This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.
@ -266,13 +266,13 @@ class Coffee < ActiveRecord::Base
end
</ruby>
The +validates_inclusion_of+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can personalize it with the current attribute's value, through the +%s+ format mask.
The +validates_inclusion_of+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can include the attribute's value using the +%s+ format specification.
The default error message for +validates_inclusion_of+ is "_is not included in the list_".
h4. validates_length_of
h4. +validates_length_of+
This helper validates the length of your attribute's value. It includes a variety of different options, so you can specify length constraints in different ways:
This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways:
<ruby>
class Person < ActiveRecord::Base
@ -287,24 +287,46 @@ The possible length constraint options are:
* +:minimum+ - The attribute cannot have less than the specified length.
* +:maximum+ - The attribute cannot have more than the specified length.
* +:in+ (or +:within+) - The attribute length must be included in a given interval. The value for this option must be a Ruby range.
* +:is+ - The attribute length must be equal to a given value.
* +:in+ (or +:within+) - The attribute length must be included in a given interval. The value for this option must be a range.
* +:is+ - The attribute length must be equal to the given value.
The default error messages depend on the type of length validation being performed. You can personalize these messages, using the +:wrong_length+, +:too_long+ and +:too_short+ options and the +%d+ format mask as a placeholder for the number corresponding to the length constraint being used. You can still use the +:message+ option to specify an error message.
The default error messages depend on the type of length validation being performed. You can personalize these messages using the +:wrong_length+, +:too_long+, and +:too_short+ options and <tt>{{count}}</tt> as a placeholder for the number corresponding to the length constraint being used. You can still use the +:message+ option to specify an error message.
<ruby>
class Person < ActiveRecord::Base
validates_length_of :bio, :too_long => "you're writing too much. %d characters is the maximum allowed."
validates_length_of :bio, :maximum => 1000,
:too_long => "{{count}} characters is the maximum allowed"
end
</ruby>
This helper counts characters by default, but you can split the value in a different way using the +:tokenizer+ option:
<ruby>
class Essay < ActiveRecord::Base
validates_length_of :content,
:minimum => 300,
:maximum => 400,
:tokenizer => lambda { |str| str.scan(/\w+/) },
:too_short => "must have at least {{count}} words",
:too_long => "must have at most {{count}} words"
end
</ruby>
The +validates_size_of+ helper is an alias for +validates_length_of+.
h4. validates_numericality_of
h4. +validates_numericality_of+
This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by a integral or floating point number. Using the +:integer_only+ option set to true, you can specify that only integral numbers are allowed.
This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by an integral or floating point number. To specify that only integral numbers are allowed set +:integer_only+ to true.
If you set +:integer_only+ to +true+, then it will use the +$$/\A[+\-]?\d+\Z/+ regular expression to validate the attribute's value. Otherwise, it will try to convert the value to a number using +Kernel.Float+.
If you set +:integer_only+ to +true+, then it will use the
<ruby>
/\A[+-]?\d+\Z/
</ruby>
regular expression to validate the attribute's value. Otherwise, it will try to convert the value to a number using +Float+.
WARNING. Note that the regular expression above allows a trailing newline character.
<ruby>
class Player < ActiveRecord::Base
@ -315,19 +337,19 @@ end
Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the following options to add constraints to acceptable values:
* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than (value)_"
* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal the supplied value. The default error message for this option is "_must be greater than or equal to (value)_"
* +:equal_to+ - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to (value)_"
* +:less_than+ - Specifies the value must be less than the supplied value. The default error message for this option is "_must e less than (value)_"
* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less or equal to (value)_"
* +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_"
* +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_"
* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than {{count}}_".
* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to {{count}}".
* +:equal_to+ - Specifies the value must be equal to the supplied value. The default error message for this option is "_must be equal to {{count}}_".
* +:less_than+ - Specifies the value must be less than the supplied value. The default error message for this option is "_must be less than {{count}}_".
* +:less_than_or_equal_to+ - Specifies the value must be less than or equal the supplied value. The default error message for this option is "_must be less or equal to {{count}}_".
* +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_".
* +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_".
The default error message for +validates_numericality_of+ is "_is not a number_".
h4. validates_presence_of
h4. +validates_presence_of+
This helper validates that the specified attributes are not empty. It uses the +blank?+ method to check if the value is either +nil+ or an empty string (if the string has only spaces, it will still be considered empty).
This helper validates that the specified attributes are not empty. It uses the +blank?+ method to check if the value is either +nil+ or a blank string, that is, a string that is either empty or consists of whitespace.
<ruby>
class Person < ActiveRecord::Base
@ -344,13 +366,13 @@ class LineItem < ActiveRecord::Base
end
</ruby>
If you want to validate the presence of a boolean field (where the real values are true and false), you should use +validates_inclusion_of :field_name, :in => [true, false]+. This is due to the way that +Object#blank?+ handles boolean values (+false.blank? # => true+).
Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use +validates_inclusion_of :field_name, :in => [true, false]+.
The default error message for +validates_presence_of+ is "_can't be empty_".
h4. validates_uniqueness_of
h4. +validates_uniqueness_of+
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint directly into your database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create an unique index in your database.
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create an unique index in your database.
<ruby>
class Account < ActiveRecord::Base
@ -358,14 +380,14 @@ class Account < ActiveRecord::Base
end
</ruby>
The validation happens by performing a SQL query into the model's table, searching for a record where the attribute that must be validated is equal to the value in the object being validated.
The validation happens by performing a SQL query into the model's table, searching for an existing record with the same value in that attribute.
There is a +:scope+ option that you can use to specify other attributes that are used to limit the uniqueness check:
<ruby>
class Holiday < ActiveRecord::Base
validates_uniqueness_of :name, :scope => :year,
:message => "Should happen once per year"
:message => "should happen once per year"
end
</ruby>
@ -377,16 +399,18 @@ class Person < ActiveRecord::Base
end
</ruby>
WARNING. Note that some databases are configured perform case-insensitive searches anyway.
The default error message for +validates_uniqueness_of+ is "_has already been taken_".
h4. validates_each
h4. +validates_each+
This helper validates attributes against a block. It doesn't have a predefined validation function. You should create one using a block, and every attribute passed to +validates_each+ will be tested against it. In the following example, we don't want names and surnames to begin with lower case.
<ruby>
class Person < ActiveRecord::Base
validates_each :name, :surname do |model, attr, value|
model.errors.add(attr, 'Must start with upper case') if value =~ /^[a-z]/
model.errors.add(attr, 'must start with upper case') if value =~ /\A[a-z]/
end
end
</ruby>