quarta-feira, 27 de novembro de 2013

Ruby on Rails - Active Record Validation

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| %>
                              

  • <%= msg %>
  •                             <% end %>
                                

                              

                            <% end %>

    Nenhum comentário:

    Postar um comentário