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.