Routing acts_as_commentable form_for submission

I have a Group model and a NewsItem model, and NewsItems are nested in Groups.

I'm trying to add acts_as_commentable powered comments to the NewsItem model, but I haven't worked out how to handle the submission of new comments when 'comments' aren't a resource in the URL. I don't have a CommentsController or a comments route (I was under the impression that they aren't necessary). I do have a 'comments/_form.html.erb' which I was going to call from the 'news_items/show.html.erb'.

Should I put a '@new_comment = Comment.new' instance variable in the news_item_controller.rb 'show' action (or any other action that will receive new comments), and use a form_for helper on the @new_comment in the view? Because that the method I was expecting to take, but I just realised I don't know how to handle 'form_for' url for the @new_comment when the comment is being created within the group_news_item_path, i.e;

<% form_for(@new_comment) do |f| %> # where do I point this? <%= render :partial => 'comments/form', :locals => { :f => f }%> <% end %>

And I also realised that this approach could create a fair bit of duplication, if I'm going to maxmise this polymorphic plugin, and re-use the comment/_form.html.erb across the 'show' actions for many other models - all my controller actions will need the Comment.new adding to them. Is there a better way or something I'm missing?

you could create a CommentsController and use hidden form fields in a shared view to tell the comments controller which type of object the comment should be associated with.

For example:

app/views/shared/_comments.rhtml

<% item = comments %>

<% for comment in item.comments %>

Comment posted by <%= comment.user.full_name %>

<%= comment.body %>

<% end %>

Comment on this <%= item.class %>

<% form_tag(comments_path) do -%>

<%= hidden_field_tag ‘comment[commentable_id]’, item.id %>

<%= hidden_field_tag ‘comment[commentable_type]’, item.class %>

<%= text_area_tag ‘comment[body]’, nil, :style => ‘width:100%; height:100px;’ %>

<%= image_submit_tag (‘post_comment_button.png’) %>

<% end %>

The above would work with the polymorphic Comment class used by acts_as_commentable

Adam

oh, that’s just a convention that I use in partials to give the passed in object a more descriptive name. In this case, however, ‘items’ isn’t all that more descriptive! :slight_smile:

In any case, the code I wrote is supposed to be called using the following form:

<%= render(:partial => ‘views/shared/comments’, :object => @product %>

and then in the ‘views/shared/_comments.rhtml’ file, the @product object that’s passed in will be accessible by the ‘comments’ local variable (remember in partials that a local variable with the same name as the partial file is automatically created for you which allows you to access the passed in object).

So you could either use

<% for comment in comments.comments %> …

which to me looks a bit confusing, or you could use

<% items = comments %>

<% for comment in item.comments %>

and of course if you wanted to be more descriptive, you could use

<% commentable_item = comments %>

which is easier to read.

Adam

Adam Cohen wrote:

oh, that's just a convention that I use in partials to give the passed in object a more descriptive name. In this case, however, 'items' isn't all that more descriptive! :slight_smile: In any case, the code I wrote is supposed to be called using the following form:

<%= render(:partial => 'views/shared/comments', :object => @product %>

and then in the 'views/shared/_comments.rhtml' file, the @product object that's passed in will be accessible by the 'comments' local variable (remember in partials that a local variable with the same name as the partial file is automatically created for you which allows you to access the passed in object).

So you could either use

<% for comment in comments.comments %> ...

which to me looks a bit confusing, or you could use

<% items = comments %> <% for comment in item.comments %>

and of course if you wanted to be more descriptive, you could use

<% commentable_item = comments %>

which is easier to read.

Adam

On Tue, Mar 18, 2008 at 5:23 AM, Neil Cauldwell <

Thanks Adam. It works, and I'll admit to being completely baffled by the <% item = comments %> at first. But it made sense when you explained that the partial creates a local variable after it's own naming convention (which in my case meant @news_item = comments = item == confusion). However, I opted for this;

My partial call does this;

<%= render :partial => "comments/comments", :object => @news_item %>

And my _comments.html.erb looks like this;

<% for comment in object.comments %> <ul class="comment">   <li><%=h comment.user.login %></li>   <li><p><%= comment.comment %></p></li>   <li><p>Posted <%= time_ago_in_words(comment.created_at) %> ago</p></li> </ul> <% end %>

<h2>Comment on this <%= object.class %></h2> <% form_tag(comments_path) do -%>   <%= hidden_field_tag 'comment[user_id]', current_user.id %>   <%= hidden_field_tag 'comment[commentable_id]', object.id %>   <%= hidden_field_tag 'comment[commentable_type]', object.class %>   <%= text_area_tag 'comment[comment]', nil, :style => 'width:100%; height:100px;' %>   <%= submit_tag 'Submit' %> <% end %>

It seems to be working just fine. Please let me know if I'm wrong to rely on 'object' as the means with which to access the :object => @news_item. It seems to make sense, though.