Forum: Ruby on Rails Error handling!

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Alastair M. (Guest)
on 2005-12-19 04:20
(Received via mailing list)
Hello all,

I'm in the beginning states of learning ruby on rails development and
have got to a part where I'm a little stuck! Basically writing a simple
blog application, just to try something completely different! ;-)

I have a page which displays the current blog entry, it's comments and
at the bottom of the page, a form to add a comment. So far, so good.
It'll add comments, list them etc. So I decided I need a validation
routine going on and used "validates_presence_of :name" in my comments
model. This is the problem I'm facing now. In past examples I've looked
at, for example when you've just scaffolded a page, the page seems to
submit back to itself if there's an error and displays the error using

<% error_messages_for 'post' %>

However, the way this seems to be working which is the same method that
the "creating a weblog in 15 minutes" video uses, the page will never
return to itself and so cannot display the error. It simply says
"comment added" and posts not passing the validation routine will not be
added. So I changed the code and have got this going on -

def comment
@comment = Post.find(params[:id]).comments.create(params[:comment])
if  @comment.save
   flash[:notice] = "added your comment."
   redirect_to :action => "show", :id => params[:title]
else
   flash[:notice] = "not added your comment."
   render :action => "show", :id => params[:title]
   end
end

Now this works, but am unable to make use of error_messages for 'post'
and unable to display the reason why the comment was not added (no name
was entered).

Help! :-) Any suggestions how I go about this?

Thanks!

Alastair
Steven S. (Guest)
on 2005-12-19 05:42
(Received via mailing list)
You need something like the following in your view (comment.rhtml
possibly or show.rhtml):

	<% error_messages_for 'comment' %>

and if the save fails you could render the action you're in if you
want to stay on the same page:

	render :action => 'comment'
Alastair M. (Guest)
on 2005-12-19 05:45
(Received via mailing list)
Steven S. wrote:
> You need something like the following in your view (comment.rhtml
> possibly or show.rhtml):
>
>     <% error_messages_for 'comment' %>
>
> and if the save fails you could render the action you're in if you  want
> to stay on the same page:
>
>     render :action => 'comment'
>

Hi Steve,

Thanks for the reply. I tried putting <% error_messages_for 'comment' %>
at the top of my show.rhtml file and got and error of

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

Extracted source (around line #1):

1: <% error_messages_for 'comment' %>
2: <%= render :partial => "post", :object => @post %>
3:
4: <h3>Comments</h3>

The show.rhtml file currently looks like -

<% error_messages_for 'comment' %>

<%= render :partial => "post", :object => @post %>

<h3>Comments</h3>
<% for comment in @post.comments %>
<%= comment.body %>
<hr>
<% end %>

<%= form_tag :action => "comment", :id => @post, :title => @post.title
%>
	<p>
		<label for="comment_name">Name</label><br>
		<%= text_field "comment", "name", :size => 50 %>
	</p>

	<p>
		<label for="comment_email">Email</label><br>
		<%= text_field "comment", "email", :size => 50 %>
	</p>

	<p>
		<label for="comment_url">Website</label><br>
		<%= text_field "comment", "url", :size => 50 %>
	</p>

	<label for="comment_body">Comment</label><br>
	<%= text_area "comment", "body", :columns => 30, :rows => 5 %><br>
	<%= submit_tag "Comment!" %>
</form>

Any ideas?

Thanks!

Alastair
Steven S. (Guest)
on 2005-12-19 06:36
(Received via mailing list)
I assume show is being called prior to someone posting a comment on a
post?  If so, that invocation of show does not have an @comment
instance variable set.

Your best bet is to change the show.rhtml to have an <%
error_messages_for 'post' %> (if it's even needed there) and change
the code in the comment method to render :action => 'comment' if the
save fails.  Be sure to include <% error_messages_for 'comment' %> in
comment.rhtml.  This should give you the errors you're looking for
and leave the user on the comment screen so they can correct it.
Alastair M. (Guest)
on 2005-12-19 23:27
(Received via mailing list)
Steven S. wrote:
>
Yeah, show is being called, which displays the blog entry plus the
comments form, so I can see how it wouldn't have an @comment instance
now.

The problem with the error message being in the comment.rhtml file is
that the comment.rhtml is ideally never called as the comments form is
shown in the show.rhtml file and that is where I'd like to show the
errors. I did create a comments.rhtml file, and put <%=
error_messages_for 'comments' as the only line in the file and that
worked and displayed the correct error. However, I would prefer for it
to be shown in the show.rhtml file if possible

thanks!

Alastair
Alastair M. (Guest)
on 2005-12-20 01:01
(Received via mailing list)
>
I've put my application online -

http://kozmo.railsplayground.com/blog/show/First+b...

If you enter a comment but leave the name out, that is what is
happening. It works, but it's not ideal. Any thoughts on how I can
display the error on the "show" page?

Cheers!

Alastair
Steven S. (Guest)
on 2005-12-20 01:13
(Received via mailing list)
How about you put the following code in show.rhtml:

	<% if @comment -%>
         	<%= error_messages_for 'comment' %>
	<% end -%>

This way if you have no @comment instance variable it won't cause the
nil object error.

Also, you'd need to change the render :action back to 'show'.
Alastair M. (Guest)
on 2005-12-20 01:59
(Received via mailing list)
Steven S. wrote:
>
Many thanks! that did the trick. I also had to get the current record in
the comment method, so it looks like

def comment
@comment = Post.find(params[:id]).comments.create(params[:comment])

if  @comment.save
	flash[:notice] = "added your comment."
	redirect_to :action => "show", :id => params[:title]
else
	render :action => 'show', id => params[:title]
end
end


but all works now! :)

Cheers for the help!

Alastair
This topic is locked and can not be replied to.