views:

14

answers:

2

I'm creating a basic blog application and I'm running into issues displaying error messages when a user tries to submit a blank comment. Instead of getting a nice looking error message, an active record error message with the correct validation erorrs. Such as
ActiveRecord::RecordInvalid in CommentsController#create
Validation failed: Name can't be blank, Email can't be blank

In my article/show view I have the following code:

<%= form_for([@article, @article.comments.build]) do |f| %>
  <%= render "shared/error_messages", :target => @article %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <p><%= f.submit %></p>
<% end %>

My error messages partial looks like this:

    <% if target.errors.any? %>
       <div id="error_explanation">
         <h2><%= pluralize(target.errors.count, "error") %> prohibited this record from                 being saved:</h2>

    <ul>
      <% target.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

I know the answer is simple but I can't figure it out.

Create action in comments controller:

def create
@article = Article.find(params[:article_id])
@comment = @article.comments.build(params[:comment])
respond_to do |format|
  if @comment.save
    format.html { redirect_to(@article, :notice => 'Comment was successfully created.') }
    format.xml  { render :xml => @article, :status => :created, :location => @article }
  else
    format.html { render :action => "articles/show" }
    format.xml  { render :xml => @comment.errors, :status => :unprocessable_entity }
  end
end
A: 

I think you're saying that you get the big grey-on-white error page, right?

Check the backtrace, but I suspect that this is coming from the create action in the controller, not the view.

If your controller uses save! with the ! at the end, that means that it will raise an error if the record is invalid. save, on the other hand, returns true or false and lets you use simple branch logic to decide how to react.

If my hunch on save! isn't right, though, please post controller code so we can dig deeper :) Thanks!

Matchu
I added the created action in the comments controller. Thanks!
RobertH
Ah, now I have the app redirecting back to the correct controller and action, but no error messages. Thanks for putting me on the right track.
RobertH
Solved, will post solution, thanks again.
RobertH
A: 

The solution was to direct the comments created action back to the correct controller/action and target @comment in my error message partial.

Final view

    <%= form_for([@article, @article.comments.build]) do |f| %>
  <%= render "shared/error_messages", :target => @comment %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <p><%= f.submit %></p>
<% end %>

Final create action in comments controller

def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.build(params[:comment])
    respond_to do |format|
      if @comment.save
        format.html { redirect_to(@article, :notice => 'Comment was successfully created.') }
        format.xml  { render :xml => @article, :status => :created, :location => @article }
      else
        format.html { render :action => "articles/show" }
        format.xml  { render :xml => @comment.errors, :status => :unprocessable_entity }
      end
    end
RobertH