# Help with forms and joined tables?

**URL:** <https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979>\
**Category:** Rails\
**Created:** [February 23, 2008, 4:04pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979 "2008-02-23T16:04:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 23, 2008, 4:04pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/1 "2008-02-23T16:04:50Z")

</div>

Hello all,

I know this is something that should be almost ridiculously easy (I am  
new with RoR, so please be gentle). I am trying to create a comment on  
a simple forum posting, but am having problems setting up my form  
properly. I am using Rails 2.0.2, but everything I find online seems to  
use the now-deprecated ‘start\_form\_tag’ and I’m not having much luck  
converting it to ‘form\_for’.

Here is my code in the show.html.erb file:

21: \<% form\_for :comment, :url =\> { :action =\> “add\_comment”, :id =\>  
@post } do |f| %\>  
22: Add a comment:  
  
23: \<%= f.text\_area :comment %\>  
24:   
  
25: \<%= submit\_tag%\>  
26: \<% end %\>

And here is my code in the posts\_controller:

def add\_comment  
Post.find(params[:id]).comments.create(params[:comment])

```
flash[:notice] = 'Comment added to the dream!'
redirect_to :action=>'show', :id=>params[:id]

```

end

Can somebody point out my mistake? TIA

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 23, 2008, 8:54pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/2 "2008-02-23T20:54:39Z")

</div>

Derek Knorr wrote:

> Hello all,

> 21: \<% form\_for :comment, :url =\> { :action =\> “add\_comment”, :id =\>  
> @post } do |f| %\>  
> 22: Add a comment:  
>   
> 23: \<%= f.text\_area :comment %\>  
> 24:   
>   
> 25: \<%= submit\_tag%\>  
> 26: \<% end %\>

> Can somebody point out my mistake? TIA

Can you please indicate as to why it’s not working… please submit your  
error log…

things I can see at first glance is that your   
's should be   
's  
(as I assume you are using html strict) and submit\_tag also takes an  
argument…

hoping to provide further assistance…

ilan

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 23, 2008, 10:52pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/3 "2008-02-23T22:52:13Z")

</div>

Sorry about that…reading back through it I see that I never actually  
said what the problem was. I have modified it per your instructions,  
but the end result is still the same as the error has something to do  
with the hash that is getting passed (I think).

Here is the updated code for the show page:

\<% form\_for :comment, :url =\> { :action =\> “add\_comment”, :id =\>  
@post } do |f| %\>  
Add a comment:  
  
\<%= f.text\_area :comment %\>  
  
  
\<%= f.submit “Save” %\>  
\<% end %\>

And here is what I have in the Post controller:

def add\_comment  
Post.find(params[:id]).comments.create(params[:comment])

```
flash[:notice] = 'Comment added'
redirect_to :action=>'show', :id=>params[:id]

```

end

I attached the error log for this action, but here is the line that  
catches my attention:

NoMethodError (undefined method `comment=’ for #Comment:0xb7ad0c34):

I don’t quite understand why it thinks ‘comment=’ is a method?

Thanks for all your help, I really appreciate this.

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 23, 2008, 11:07pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/4 "2008-02-23T23:07:58Z")

</div>

Hello,  
I had a similar problem the other day. Change your form tag to this:

\<%= form\_tag :controller =\> ‘YourController’, :action =\> ‘add\_comment’  
-%\>

where YourController is… well, the name of your controller. End it  
with:

\<%= end\_form\_tag -%\>

using this method, you don’t need to use the \<%= f.text\_area %\> thing,  
but instead just use regular HTML textboxes. If you specify your HTML  
textbox name to be ‘comment’, you can access it in your controller by  
using params[:comment].

However, I’m pretty sure you still have to use the ruby submit button:

\<%= submit\_tag ‘save’ -%\>

Give it a whirl, hopefully it works for you. I’m pretty new to RoR too,  
but this worked for me.

- Jeff

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 23, 2008, 11:34pm UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/5 "2008-02-23T23:34:53Z")

</div>

Hey guys, that got me on the right track! I used the form\_tag, but had  
to remove the ‘=’ and also add a ‘do’ for it to work. I also just used  
a HTML textarea element named ‘comment’. That got the view corrected,  
but I then started receiving an error saying:

undefined method ‘stringify keys!’ for “text added for comment  
example”:String

To remedy that, I updated the controller so that the field to which I  
was inserting (body) was explicitly named like this:

```
Post.find(params[:id]).comments.create(:body => params[:comment])

```

Thanks Jeff and Ilan for the assist!

Derek

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 24, 2008, 2:23am UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/6 "2008-02-24T02:23:23Z")

</div>

Derek Knorr wrote:

> ```
> Post.find(params[:id]).comments.create(:body => params[:comment])
> 
> ```

This suggests your Comment model’s attribute is “body”. It seems  
unlikely that you have a special page just to create a comment, so I’m  
going to assume that this form is on the Post show view. What you  
probably need then is something like this:

## Post controller:

def show

# Get the post and all current comments for display

# including the comments here means 1 hit on the db

@post = Post.find(params[:id], :include =\> :comments)

# Create a blank comment to feed to the form

@comment = Comment.new

# any other initialisation stuff

## end

## The show view (just the bit for the new comment):

## \<% form\_for :comment, :url =\> {:action =\> :add\_comment, :id =\> @post} do |f| %\> Add a comment: \<%= f.text\_area :body %\> \<%= f.submit “Save” %\> \<% end %\>

## back in the controller:

## def add\_comment Post.find(params[:id]).comments.create(params[:comment]) end

The reason for this is that the name of the form (here :comment) means  
to take the instance variable of the same name (so @comment) set in the  
controller for the current default values. The names of the fields (now  
:body in my example) mean use that attribute of the form object (so  
@comment.body here) as the default value for that field. Since the  
comment is a blank one, we’ll get a blank field.

When the form is submitted, it will send parameters back to the  
controller with keys :id (from the url spec) and :comment (from the name  
of the form). The parameter with key :comment will have a hash as a  
value. That hash will have keys of field names and values of the data  
from the field. So, if you entered “comment text” in the form and the  
post was id 1, the parameters sent to add\_comment would be the  
equivalent of:  
{:id =\> 1, :comment =\> {:body =\> “comment text”}}

This is why we can use params[:comment] now as an argument to the create  
(it is exactly the hash you need). The reason for your no comment=  
method should now be apparent. Because you used :comment as the name of  
your text field, the parameters list sent back to the controller was the  
equivalent of:  
{:id =\> 1, :comment =\> {:comment =\> “comment text”}}

The second :comment there was being interpreted as the field to set, so  
it was trying to call the comment= method to do this.

Whenever I am playing with forms in Rails, I always compare the view  
with the generated HTML and the parameters sent back to the controller  
(from the log file) so that I am clear where values are coming from and  
going to. It can save a lot of headaches.

---

<div class="post-metadata">

**Author:** ![djknorr75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/71e660/32.png) [@djknorr75](https://www.ruby-forum.com/u/djknorr75)\
**Post date:** [February 24, 2008, 4:20am UTC](https://www.ruby-forum.com/t/help-with-forms-and-joined-tables/129979/7 "2008-02-24T04:20:44Z")

</div>

Mark,

That was an excellent explanation. This is the way I pictured it  
working, just didn’t know how to get there from where I was at. It’s  
starting to make sense!

Thanks,

Derek
