Rails Study(VII)Validations and Callbacks

阅读更多
Rails Study(VII)Validations and Callbacks

1. The Object Life Cycle
Validations allow you to ensure that only valid data is stored in database.
Callbacks and observers allow you to trigger logic before or after an alteration of an object's state.

2. Validations Overview
2.1 Why Use Validations?
native database constraints,
client-side validations,
controller-level validations,
model-level validations

2.2 When Does Validation Happen?
>rails generate model Person name:string
>rake db:migrate
It really strange, the newly created table named People, the model class named person.rb.

Open rails console and have a test
>rails console
> p = Person.new(:name => 'Carl')
=> #
> p.new_record?
=> true
> p.save
  SQL (13.0ms)  BEGIN
  SQL (701.0ms)  INSERT INTO `people` (`created_at`, `name`, `updat
ed_at`) VALUES (?, ?, ?)  [["created_at", Fri, 05 Aug 2011 06:04:37 UTC +00:00],
["name", "Carl"], ["updated_at", Fri, 05 Aug 2011 06:04:37 UTC +00:00]]
   (1.0ms)  COMMIT
=> true
> p.new_record?
=> false

There are 2 kinds of objects. One is saved in database, one has no relationship with database yet.

2.3 Skipping Validations
save(:validate => false)

2.4 valid? and invalid?
class Person < ActiveRecord::Base
  validates :name,  :presence =>true
end

> Person.create(:name=>"carl").valid?
=> true
> Person.create(:name=>nil).valid?
=> false

>>p = Person.new
>>p.valid?
=>false
>>p.errors
=>{:name=>["can't be blank"]}

2.5 errors[]
errors[:attribute], it returns an array of all the errors for :attribute.
>>Person.new.errors[:name].any?
=> false
>>Person.create.errors[:name].any?
=> true
>>Person.create.errors[:name]
=> ["can't be blank"]

3. Validation Helpers
3.1 validates_acceptance_of
Validates that a checkbox on the user interface was checked when a form was submitted.
validates_acceptance_of :terms_of_service

3.2 validates_associated
has_many :books
validates_associated :books

3.3 validates_confirmation_of
We need to use this helper when we have 2 text fields that should receive exactly the same content.
class Person < ActiveRecord::Base
   validates_confirmation_of :email
   validates_presence_of :email_
end

<%= text_field :person, :email %>
<%= text_field :person, :email_confirmation %>

3.4 validates_exclusion_of
3.5 validates_format_of
validates_format_of :legacy_code, :with => /\A[a-zA-Z]+\z/, :message => "only leters allowed"

3.6 validates_inclusion_of
3.7 validates_length_of
validates_length_of :name, :minimum =>2
validates_length_of :name, :maximum => 500
validates_length_of :password, :in => 6..20            #:in(or :within) the attribute length must be included in a given interval.
validates_length_of :registration_number, :is => 6   # the attribute length must be equal to the given value

validates_length_of :bio, :maximum =>1000, :too_long => "%{count} characters is the maximum allowed"

3.8 validates_numericality_of
validates_numericality_of :points
validates_numericality_of :games_played, nly_integer => true

:greater_than
:greater_than_or_equal_to
:equal_to
:less_than
:less_than_or_equal_to
:odd
:even

3.9 validates_presence_of
class Person < ActiveRecord::Base
  validates_presence_of :name
end

>>Person.create.valid?
=> false
>>Person.create(:name=>'joan').valid?
=> true

validates_presence_of :name, :login, :email

3.10 validates_uniqueness_of
validates_uniqueness_of :email
validates_uniqueness_of :name :case_sensitive => false

3.11 validates_with
3.12 validates_each

4. Common Validation Options
4.1 :allow_nil
4.2 :allow_blank
4.3 :message
4.4 n
The n option lets you specify when the validation should happen.
class Person < ActiveRecord::Base
    validates_uniqueness_of :email, n => :create
    validates_numericality_of :age, n => :update
    validates_presence_of :name, n => :save
end

5. Conditional Validation
5.1 Using a Symbol with :if and :unless
class Order < ActiveRecord::Base
   validates_presence_of :card_number, :if => :paid_with_card?

   def paid_with_card?
     payment_type == "card"
   end
end

5.2 Using a String with :if and :unless
validates_presence_of :surname, :if => "name.nil?"

5.3 Using a Proc with :if and :unless
6 Creating Custom Validation Methods
class Invoice < ActiveRecord::Base
   validate :expiration_date_cannot_be_in_the_past,
              :discount_cannot_be_greater_than_total_value

   def expiration_date_cannot_be_in_the_past
      errors.add(:expiration_date, "can't be in the past") if
         !expiration_date.blank? and expiration_date < Date.today
   end

   def discount_cannot_be_greater_than_total_value
      errors.add(:discount, "can't be greater than total value") if
        discount > total_value
   end
end

references:
http://guides.rubyonrails.org/active_record_validations_callbacks.html

你可能感兴趣的:(validations,activerecord,rails)