How do I display error messages for nested resource validations?
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
I had a similar problem. everything seemed to work fine, but I was not getting any errors The solution i found is to build the comment in article#show instead of the view:
@article = Article.find(params[:id])
@comment = @article.comments.build(params[:comment])
and in your articles#show don't use @article.comments.build but @comment:
<%= form_for([@article, @comment]) do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<p><%= f.submit %></p>
<% end %>
make sure you build the comment in your comment#create as well (you really have no choice though :P)
also, I don't know if it matters (i'm pretty new to ruby), but I think you need to pass f.object instead of @comment.
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!
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
精彩评论