Rails Model Validation
Validation
ActiveModel::Validations::XxxxxValidator class.
Check model attributes.
- acceptance
- confirmation
- exclusion
- inclusion
- format
- length
- numericality
- presence
- absence
- uniqueness
Example and Basics
Data
title presence, length 1 - 100 price integer < 10000 category candidate A/B/C/D/E
Model
class Item < ActiveRecord::Base validates :title, presence: true, length: { minimum: 1, maximum: 100 } validates :price, numericality: { only_integer: true, less_than: 10000 } validates :category, includesion: { in:['A','B','C','D', 'E'] } end [/ruby] Model create [ruby] def create @item = Item.new(item_params) respond_to do |format| if @item.save # success else # fail end end end [/ruby] validation is executed when save is called. <h4>Apply validation</h4> create, create!, save, save!, update, update! <h3>Show error in view</h3> create, create!, save, save!, update, update! [ruby] <% if @item.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@item.errors.count, "error") %> prohibited this item from being saved</h2> <ul> <% @item.errors.full_message.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
acceptance
Allow user regulation : No need to add database attr
Example) User Info(users_controller.rb)
def user_params params.require(:user).permit(:username, :password, :email, :agreement) end
Model
class User < ActiveRecord::Base validates :agreement, acceptance: true end [/ruby] users/_form.html.erb [ruby] <%= f.text_field :roles %> <div class="field"> <%= f.label :agreement %><br> <%= f.check_box :agreement %> </div> <div class="actions"> <%= f.submit %> </div>
confirmation
password, email double input check
users_controller.rb
def user_params params.require(:user).permit(:username, :password, :email, :email_confirmation, :agreement) end
user.rb
class User < ActiveRecord::Base validates :email, confirmation: true end [/ruby] users/_form.html.erb [ruby] <div class="field"> <%= f.label :email %><br> <%= f.text_field :email %> </div> <div class="field"> <%= f.label :email_confirmation %><br> <%= f.text_field :email_confirmation %> </div>
Use field with _confirmation as confirmation
xxxxxx
xxxxxx_confirmation
uniqueness
validate :name, uniqueness: { scope: :team }
We can add scope
name is unique within team, team is other column
Validation parameters
Examples
parameter | description |
---|---|
allow_nil | if nil, skip validation |
allow_blank | if blank, skip validation |
message | error message |
on | validation timing(create, update, save) |
if | if true, do validation |
unless | if true, do validation |
How to use
validates :uid, # column presence: true, uniqueness: { allow_blank: true }, length: { is: 20, allow_blank: true }
acceptance should be applied only create
class User < ActiveRecord::Base validates :agreement, acceptance: { on: :create } end [/ruby] <h4>message</h4> [ruby] class Item < ActiveRecord::Base validates: :name, presence: { message: 'is required'}, uniqueness: { allow_blank: true, message '%{value} is unique' } end [/ruby] <h4>if/unless</h4> [ruby] class User < ActiveRecord::Base validates :email, presence: { unless: 'letter.blank?' } end [/ruby] If the letter isn't blank, check email presence <hr> <h3>My Validation class</h3> The class should be extended <strong>ActiveModel::EachValidator</strong> [ruby] class TitleValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add(attribute, ' is not correct') unless value.length < 0 end end [/ruby] record : target object attribute : field name value : value <h4>How to use</h4> validation name is class name from Validator In case of above, <strong>title</strong> is validation name [ruby] validates :title, presence: true, title: true
How to get parameter from validation
option[:parametername: true}
title: { parametername: true }