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 }
