Topic: Validation Error Box Customisation

I'm coding my first major Rails app and want to customise some things on the validation.

I have the fields validating fine - this isn't a problem. I've also change the colours of the error box by editing the CSS.

What I want to change is the following:

[1] The title shown in the error box: "3 errors prohibited this signup from being saved" - how would I change this to say "There were 3 errors when processing your form"

[2] The errors given say something like:

Realname You must tell us your name!
Email An email address is required!

How do I customise this not to show the field names (ie Realname, Email) before the error message?

Re: Validation Error Box Customisation

If you take a look at the source for the error_messages_for method you can see what it is doing. This loops through the @model.errors.full_messages array, but you can just do @model.errors.each to separate the attribute name from the message:

<ul>
<% @model.errors.each do |attr, msg| %>
  <li><%= msg %></li>
<% end %>
</ul>

You'll need to remake the header message how you want it.

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

I'm a little confused as to which files I have to modify now? I tried putting the code you suggested on my _form.rhtml page and it throws an error:

NoMethodError in Signup#new

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occured while evaluating nil.errors

Re: Validation Error Box Customisation

Did you substitute @model with the name of your model?

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

Thanks. I can be so thick at times..

Now I've got the following code:

<div class="errorExplanation" id="errorExplanation"><h2>There were errors with your application!</h2>
    <p>The following problems occured:</p>
    <ul>
        <% @signup.errors.each do |attr, msg| %>
          <li><%= msg %></li>
        <% end %>
    </ul>
</div>

Everytime the page is viewed, even if there aren't errors, the box is displayed. How do I make it so that the box isn't display/the code isn't executed if there are no errors?

Re: Validation Error Box Customisation

You can do this:

<% unless @signup.errors.empty? %>
  # display error box
<% end %>

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

I'm reusing this code in another project now and for some reason it won't work quite as it should.

The following error is thrown:

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.errors

The model name is "signup" and this is the code I'm using for the error showing:

<% unless @signup.errors.empty? %>
<div class="errorExplanation" id="errorExplanation"><h2>There were errors with your application!</h2>
    <p>The following problems occured:</p>
    <ul>
        <% @signup.errors.each do |attr, msg| %>
          <li><%= msg %></li>
        <% end %>
    </ul>
</div>
<% end %>

If I remove this code from the view and revert back to the default error messaging, the form works fine. If I put the code back in and resubmit the form, it works fine and displays the customised errors as it should.

Am I forgetting to initialise something somewhere?

Re: Validation Error Box Customisation

Did you set the @signup variable in the controller? Please post that.

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

The controller is as follows:

class SignupController < ApplicationController
  def index
    render :action => 'new'
  end

  def new
    @signup = Signup.new
  end

  def create
    @signup = Signup.new(params[:signup])
    if @signup.save
      redirect_to :action => 'success'
    else
      render :action => 'new'
    end
  end
 
  def success
   
  end
end

Re: Validation Error Box Customisation

Everything looks good from what I can tell. I'm assuming you are only calling @signup.errors in the new.rhtml template and no where else, correct?

jmaskell wrote:

If I remove this code from the view and revert back to the default error messaging, the form works fine. If I put the code back in and resubmit the form, it works fine and displays the customised errors as it should.

I'm confused by this. At first it didn't work, then you swapped the code with the default and it started working, and now it works with the old code? Does this mean everything is working now?

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

ryanb wrote:

Everything looks good from what I can tell. I'm assuming you are only calling @signup.errors in the new.rhtml template and no where else, correct?

It's called from the _form.rhtml, but this just gets included on the new.rhtml.

ryanb wrote:

I'm confused by this. At first it didn't work, then you swapped the code with the default and it started working, and now it works with the old code? Does this mean everything is working now?

It doesn't work the first time you access the page and a blank form is rendered - if the custom code is there, it throws an error. If I take out the code, then let the form render, then put the code back in, it works as it should.

If the code is there before the form is first rendered, it'll throw an error.

Re: Validation Error Box Customisation

Interesting, so it doesn't work when rendering the "new" action, but it does later when doing the "update" action. Try putting this near the top of the new.rhtml file:

<%= debug(@signup) %>
<%= @signup.class %>

This will tell you some information about the variable to make sure it is set properly.

If you just want a quick fix, you can do this before displaying the errors.

<% unless @signup.nil? || @signup.errors.empty? %>

Railscasts - Free Ruby on Rails Screencasts

Re: Validation Error Box Customisation

I've now got this working and have the following problem:

The message for validates_length_of never gets passed through. The default just gets used.

The code I'm used is:

  validates_length_of       :email,    
                            :within => 3..100,
                            :message => "Your email address is an incorrect length"