The controller:
class WeblogController < ActionController::Base
def show # not used directly, just example
@post = Post.find(params["id"])
end
def new
@post = Post.new
end
def create
@post = Post.new(params["post"])
if @post.save
redirect_to :action => "show", :id => @post.id
else
render_action "new"
end
end
end
The new template:
<% unless @post.errors.empty? %>
The post couldn't be saved due to these errors:
<ul>
<% @post.errors.each_full do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<%= form "post" %>
or even shorter:
<%= error_messages_for 'post' %>
The model (0.9):
class Post < ActiveRecord::Base
validates_presence_of :title, :body, :message => "Missing required field"
validates_length_of :title, :maximum => 10, :message => "Title too long - max 10 characters"
end
The model (pre 0.9):
class Post < ActiveRecord::Base
protected
def validate
errors.add_on_empty(["title", "body"])
errors.add("title", "must be at most 10 characters") if title.size > 10
end
end
The Validation Documentation has all sorts of details about what methods are available. Also check out the validation class methods available in Rails 0.9.
Note: _validates_confirmation_of_ is very weak. If the *_confirmation field is nil, the confirmation does not take place. This makes it easy for poorly written code to by pass the confirmation.
_validates_acceptance_of also accepts nil values by default. If you write your controllers test-first (and you should — it’s so good that you can), acceptance_of tests will pass falsely if you do not pass them a value.
To show the error message in your view:
<%= error_messages_for 'model_name_goes_here' %>
Conditional validation can be done using the :if attribute of the validation methods. For example, if you need to validate the numericality of a field but also need that field to be optional:
validates_numericality_of :age, :if => :age?
Or, if you need to perform some sort of processing in order to determine whether or not to validate:
validates_numericality_of :age, :if => Proc.new { |age| !age.blank? }
Using Proc.new with the block is necessary since :if has specific requirements about what can be passed to it (quoting the error message Rails provides):
Validations need to be either a symbol, string (to be eval'ed), proc/method, or class implementing a static validation method
If you find yourself having to deal with validation (error messages) in Rails, you might want to check out this article by me, Bigsmoke.
Here is a useful printable cheatsheet on Rails Validations
category:Howto
category:OpenQuestion