Controller/view problem from RoR n00b

can anybody tell me why my controller is not creating a new comment,
but my view lists comments that i manually add to the database?

here is my view code:

<% for comment in @post.post_comments %>
	<%= comment.body %>
	<%= comment.email_address %>
<% end %>

<%= form_tag :action => "comment", :id => @post %>
<%= text_area "post_comment", "body" %><br/>
<%= submit_tag "Comment!" %>
</form>

and here is my controller code:

def comment
Post.find(params[:id]).post_comments.create(params[:post_comment])
flash[:notice] = “Added your comment.”
redirect_to :action => “show”, :id => params[:id]
end

i have models called post and post_comment and tables called posts and
post_comments.

i don’t get any error messages and it redirects back to the appropriate
post on the show page, but the flash doesn’t work and the comment isn’t
added.

On 29-Oct-06, at 2:20 PM, Luke wrote:

redirect_to :action => "show", :id => params[:id]

Hey Luke,

your problem lies with Instance versus Class methods.

Post.find(params[:id]).post_comments.create(params[:post_comment])

Post.find returns an array of post instances. The instance method
post_comments returns an array of comments instances.

The create method doesn’t belong either to a particular comment
instance, nor to Array.

You should be calling Post.create and adjusting your params as such.

Plus if you check your development.log, you’ll likely see something
like “create is not a method of Array”. This log should be a key
source of debugging.

J

The above post is not correct.

Post.find only returns a single object if only one is found (i.e. when
finding by params[:id] as above).

post.post_comments is an association proxy that will return an array of
related PostComment objects but, you can also call methods such as
create on it as well. See the API docs for more information.

The above post is not correct.

Post.find only returns a single object if only one is found (i.e. when
finding by params[:id] as above).

post.post_comments is an association proxy that will return an
array of
related PostComment objects but, you can also call methods such as
create on it as well. See the API docs for more information.

I stand corrected. Thank you.

This is one area of the documentation (IMO) is weak . But consulting
through irb, and .methods .instance_methods ljredpath is correct.

J

Thanks for the response. I follow you on the first part where you say
“Post.find only returns a single object if only one is found (i.e. when
finding by params[:id] as above).”, but I lost you on the second part. I
will definitely check the API documentation, but I’m not sure where to
look. Can you explain the second part in a little more detail or refer
me to the proper area of the API docs?

Thanks,

Luke

unknown wrote:

The above post is not correct.

Post.find only returns a single object if only one is found (i.e. when
finding by params[:id] as above).

post.post_comments is an association proxy that will return an array of
related PostComment objects but, you can also call methods such as
create on it as well. See the API docs for more information.

Why having a model called post_comments? If you have comments belong to
more then 1 model then you can use Single Type Inheritance.

about
def comment
if post = Post.find(params[:id])
@com = post.post_comments.build(params[:post_comment])
if @com.save
flash[:notice] = “Added your comment.”
redirect_to :action => “show”, :id => params[:id]
end
else
render :text => “Cannot find post”
end
end

And where you have your form to create comments you can have small
section for error message to find our what goes wrong

Gokhan A.
www.sylow.net

I’m not familiar with single type inheritance. The reason I have
post_comments is because I also have picture_comments and I need a way
to differentiate between the two. I’ll have to look into your suggestion
and see if it will work for me. Thanks.

Gokhan A. wrote:

Why having a model called post_comments? If you have comments belong to
more then 1 model then you can use Single Type Inheritance.

about
def comment
if post = Post.find(params[:id])
@com = post.post_comments.build(params[:post_comment])
if @com.save
flash[:notice] = “Added your comment.”
redirect_to :action => “show”, :id => params[:id]
end
else
render :text => “Cannot find post”
end
end

And where you have your form to create comments you can have small
section for error message to find our what goes wrong

Gokhan A.
www.sylow.net

gokhan,

your code below doesn’t seem to be working. i suspect that i have
something else going on. is there somewhere that i can look (a log file
or something) to see if errors are being generated, but not displayed on
the screen. it seems kind of odd to me that the code isn’t working, but
there is no evidence of failure.

thanks,

luke

Luke wrote:

I’m not familiar with single type inheritance. The reason I have
post_comments is because I also have picture_comments and I need a way
to differentiate between the two. I’ll have to look into your suggestion
and see if it will work for me. Thanks.

Gokhan A. wrote:

Why having a model called post_comments? If you have comments belong to
more then 1 model then you can use Single Type Inheritance.

about
def comment
if post = Post.find(params[:id])
@com = post.post_comments.build(params[:post_comment])
if @com.save
flash[:notice] = “Added your comment.”
redirect_to :action => “show”, :id => params[:id]
end
else
render :text => “Cannot find post”
end
end

And where you have your form to create comments you can have small
section for error message to find our what goes wrong

Gokhan A.
www.sylow.net

Luke wrote:

is there somewhere that i can look (a log file or something)

Look under /RAILSROOT/log/development.log (or production.log for
production)

Your best bet though is to try doing a breakpoint in your comment method
and see whats actually going on…

http://wiki.rubyonrails.org/rails/pages/HowtoDebugWithBreakpoint

Cheers

Luke No 1 :wink:

ok, i started through the breakpoint tutorial above, but when i try to
start the breakpointer using:

./script/breakpointer

from within my rails app base directory, i get:

./script/…/config/boot.rb:18:in require': No such file to load -- rubygems (LoadError) from ./script/../config/boot.rb:18 from script/breakpointer:2:inrequire’
from script/breakpointer:2

anyone know how to fix this?

Thanks Luke. That should help.

Luke P. wrote:

Luke wrote:

is there somewhere that i can look (a log file or something)

Look under /RAILSROOT/log/development.log (or production.log for
production)

Your best bet though is to try doing a breakpoint in your comment method
and see whats actually going on…

http://wiki.rubyonrails.org/rails/pages/HowtoDebugWithBreakpoint

Cheers

Luke No 1 :wink:

nevermind, i got it. had to install rubygems… duh… like i said, i’m
a noobie :slight_smile:

Luke Borloz wrote:

ok, i started through the breakpoint tutorial above, but when i try to
start the breakpointer using:

./script/breakpointer

from within my rails app base directory, i get:

./script/…/config/boot.rb:18:in require': No such file to load -- rubygems (LoadError) from ./script/../config/boot.rb:18 from script/breakpointer:2:inrequire’
from script/breakpointer:2

anyone know how to fix this?

Ok, now I got the breakpointer working, but for some reason, my comments
are still not saving.

I’m going to post everything that I have and hopefully someone will be
able to tell me where I’m going wrong…

Here is my controller code:

def comment
post = Post.find(params[:id])
@comment = post.post_comments.build(params[:post_comment])
breakpoint
if @comment.save
flash[:notice] = “Added your comment.”
redirect_to :action => “show”, :id => params[:id]
else
flash[:notice] = “Unable to save your comment.”
redirect_to :action => “show”, :id => params[:id]
end
end

And here is what I’m getting in my log as a result:

Processing BlogController#comment (for 127.0.0.1 at 2006-11-01 22:45:25)
[POST]
Session ID: fc25db96c14d3bf349e3e52cbd311bcc
Parameters: {“post_comment”=>{“body”=>“test”}, “commit”=>“Comment!”,
“action”=>“comment”, “id”=>“3”, “controller”=>“blog”}
Post Load (0.000826) SELECT * FROM posts WHERE (posts.id = ‘3’)
LIMIT 1
Post Columns (0.006130) SHOW FIELDS FROM posts
PostComment Load (0.007839) SELECT * FROM post_comments WHERE
(post_comments.post_id = 3)
PostComment Columns (0.020313) SHOW FIELDS FROM post_comments
SQL (0.000301) BEGIN
SQL (0.000296) COMMIT
Redirected to http://0.0.0.0:3000/blog/show/3
Completed in 5.10297 (0 reqs/sec) | DB: 0.03571 (0%) | 302 Found
[http://0.0.0.0/blog/comment/3]

Processing BlogController#show (for 127.0.0.1 at 2006-11-01 22:45:31)
[GET]
Session ID: fc25db96c14d3bf349e3e52cbd311bcc
Parameters: {“action”=>“show”, “id”=>“3”, “controller”=>“blog”}
Post Load (0.000811) SELECT * FROM posts WHERE (posts.id = ‘3’)
LIMIT 1
Rendering within layouts/application
Rendering blog/show
Post Columns (0.007676) SHOW FIELDS FROM posts
PostComment Load (0.014388) SELECT * FROM post_comments WHERE
(post_comments.post_id = 3)
Completed in 0.11120 (8 reqs/sec) | Rendering: 0.07924 (71%) | DB:
0.02288 (20%) | 200 OK [http://0.0.0.0/blog/show/3]

At the breakpoint in my above controller code, here is the value of
@commment:

@comment
=> #<PostComment:0x26bcce4 @new_record=true,
@attributes={“body”=>“test”, “date”=>nil, “created_by”=>nil,
“post_id”=>3, “website_address”=>nil, “email_address”=>nil}>

Here is my post_comments table:

CREATE TABLE post_comments (
id int(11) NOT NULL auto_increment,
body text NOT NULL,
created_by varchar(255) default NULL,
email_address varchar(255) default NULL,
website_address varchar(255) default NULL,
date datetime default NULL,
post_id int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 AUTO_INCREMENT=1
;

I’m at a loss at this point. It seems like I’ve tried everything, but
I’m sure I’m missing something minor.

Any help will be appreciated.

Thanks,

Luke

Got it now!! I had a validates_presence_of in my model for a field that
I had deleted from the table. Anyone have any idea why rails doesn’t
tell you when you make a dumb mistake like that??

If you look at:

You’ll see, under the section for has_many, a list of the methods
available.

If you look at:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/
ClassMethods.html

You’ll see, under the section for has_many, a list of the methods
available.

as sure as Bob’s your uncle, I stand corrected again. I hope I’m not
making a habit of this!

J

Thanks for the response. I follow you on the first part where you say
“Post.find only returns a single object if only one is found (i.e. when
finding by params[:id] as above).”, but I lost you on the second part.
I will definitely check the API documentation, but I’m not sure where
to look. Can you explain the second part in a little more detail or
refer me to the proper area of the API docs?

Thanks,

Luke

On Thu, 2006-11-02 at 05:22 +0100, Luke Borloz wrote:

Got it now!! I had a validates_presence_of in my model for a field that
I had deleted from the table. Anyone have any idea why rails doesn’t
tell you when you make a dumb mistake like that??


logs are your friend

Craig

That was my question. I didn’t see it in any of my logs. It doesn’t seem
to throw any type of error anywhere when you do this.

Craig W. wrote:

On Thu, 2006-11-02 at 05:22 +0100, Luke Borloz wrote:

Got it now!! I had a validates_presence_of in my model for a field that
I had deleted from the table. Anyone have any idea why rails doesn’t
tell you when you make a dumb mistake like that??


logs are your friend

Craig

create doesn’t raise an error when validation fails, it just returns
false , so check those return values :slight_smile:

Fred