Active
Record Validation
=============
Based on guides.rubyonrails.org
Validation happens when
class.new_record? is called
Ex:
p = Person.new(name:
"John Doe")
#
#p.new_record?
#true
p.save
#true
p.new_reccord?
false
Validation acts on:
create
create!
save
save!
update
update!
These methods skip validation
decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_columns
update_counters
save(validate: false)
valid? invalid?
Person.create(name:
nil).valid? # => false
errors[]
After validation, each
error will be stores in a array object.errors
Person.new.errors[:name].any?
person = Person.new
person.valid? # =>
false
person.errors[:name]
If no error, return []
add
It is possible to add
error
errors.add(:name,
"cannot contain the characters !@#%*()_-+=")
error [:base]
It is array that always
exists, but is empty. Can include error
errors[:base]
<< "This person is invalid because ..."
Messages can be includes
as it is an array. Message will be shown
in error message.
Clear and Empty
person.errors.clear
person.errors.empty? #
=> true
size
person.errors.size #
=> 2
Each erro
person.errors.full_messages.each
do |msg|
puts
msg
end
When
a error occurs a
is created to b
Validation Helper
Pre-defined validation
helpers that can be used directly
Acceptance
Validates
checkbox of acceptance of some company condition for example.
class Person
< ActiveRecord::Base
validates
:terms_of_service, acceptance: true
#OR
validates
:terms_of_service, acceptance: { accept: 'yes' }
end
Message: "must be accepted"
validates_associated
If valid? the
main object(ex:Library), all associations(ex:Books) should be validated
class Library
< ActiveRecord::Base
has_many :books
validates_associated :books
end
confirmation
when two
fields should receive the same value
Ex:
class
Person < ActiveRecord::Base
validates :email, confirmation: true
validates :email_confirmation, presence: true
end
In view
appears:
<%=
text_field :person, :email %>
<%=
text_field :person, :email_confirmation %>
exclusion
To exclude a
specific value. use "in:" to
specify
class Account
< ActiveRecord::Base
validates :subdomain, exclusion: { in: %w(www
us ca jp),
message: "Subdomain %{value} is
reserved." }
end
format
Specify a
accepted format
class Product
< ActiveRecord::Base
validates :legacy_code, format: { with:
/\A[a-zA-Z]+\z/,
message: "Only letters allowed" }
end
inclusion
If a value is
in a set
class Coffee
< ActiveRecord::Base
validates :size, inclusion: { in: %w(small
medium large),
message: "%{value} is not a valid
size" }
end
lenght
Accepted
lenght
class Person
< ActiveRecord::Base
validates :name, length: { minimum: 2,
maximum: 500,
too_short: "must have at least %{count}
words",
too_long: "must have at most %{count}
words" }
validates :password, length: { in: 6..20 }
validates :registration_number, length: { is:
6 }
end
numerically
Accept only
number
class Player
< ActiveRecord::Base
validates :points, numericality: true
validates :games_played, numericality: {
only_integer: true } #/\A[+-]?\d+\Z/
end
Other
options:
:greater_than,
:greater_than_or_equal_to, :equal_to, :less_than, :less_than_or_equal_to, :odd,
:even,
Presence
Verify the
presence of an attribute
class
LineItem < ActiveRecord::Base
belongs_to :order
validates :order, presence: true
end
- inverse_of
In
line_items, Order is mandatory, uses inverse_of
class
Order < ActiveRecord::Base
has_many :line_items, inverse_of: :order
end
absence
If you need
some field to be blank or empty
class Person
< ActiveRecord::Base
validates :name, :login, :email, absence:
true
end
Same as
presence to association
uniqueness
enforce
uniqueness
class Account
< ActiveRecord::Base
validates :email, uniqueness: true
validates :name, uniqueness: {
case_sensitive: false }
end
validates_with
Passed the
validation to another class
class Person
< ActiveRecord::Base
validates_with GoodnessValidator
end
class
GoodnessValidator < ActiveModel::Validator
def validate(record)
if record.first_name == "Evil"
record.errors[:base] << "This
person is evil"
end
end
end
validates_each
validates
attributes in a block
class Person
< ActiveRecord::Base
validates_each :name, :surname do |record,
attr, value|
record.errors.add(attr, 'must start with
upper case') if value =~ /\A[a-z]/
end
end
Common Validation Options
:allow_nil
:allow_blank
:message
:on
Specify when
then validation should happen (:create, :update)
# it will be
possible to create the record with a non-numerical age
validates
:age, numericality: true, on: :update
Strict Validations
Conditional Validation
Use of :if or :unless
class Order
< ActiveRecord::Base
validates :card_number, presence: true, if:
:paid_with_card?
def paid_with_card?
payment_type == "card"
end
end
class Person
< ActiveRecord::Base
validates :surname, presence: true, if:
"name.nil?"
end
Using Proc with :if or
:unless
class Account
< ActiveRecord::Base
validates :password, confirmation: true,
unless: Proc.new { |a| a.password.blank? }
end
Grouping conditions
Uses
with_options
class User
< ActiveRecord::Base
with_options if: :is_admin? do |admin|
admin.validates :password, length: {
minimum: 10 }
admin.validates :email, presence: true
end
end
Custom Validations
Creating a Validator
Extends the
class ActiveModel::Validator and call the validator using: validates_with
class
MyValidator < ActiveModel::Validator
def
validate(record)
end
end
class Person
include ActiveModel::Validations
validates_with MyValidator
end
Creating methods
class Class
< ActiveRecord::Base
validate
:methodToValidate, on :create
def
methodToValidate
errors.add(:attribute, "can't be in
the past")
end
end
end
Errors in view
<% if
@post.errors.any? %>
<%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:
<%
@post.errors.full_messages.each do |msg| %>
<%
end %>
<% end %>
Nenhum comentário:
Postar um comentário