11

The README does not show how to handle the controller and view aspects of setting up this plugin. I have been searching for a couple hours and can't find anything that shows how to use this plugin.

Makoto
  • 104,088
  • 27
  • 192
  • 230
eksatx
  • 1,023
  • 2
  • 10
  • 15
  • 0 down vote Ryan Bates has a nice screen cast on how to build comments: http://railscasts.com/episodes/154-polymorphic-association-revised He's creating the polymorphic associations from scratch, but essentially it works the same as using the act_as_commentable gem. He shows how to add the controller, routes and views. – MZaragoza May 04 '15 at 01:13

3 Answers3

18

After even more searching, I gave up on finding a tutorial and came up with this. If anyone can point out a better / cleaner way to do this, please let me know. Otherwise, here is what I am using now in case this will benefit anyone else.

First, install the plugin with script/plugin install http://github.com/jackdempsey/acts_as_commentable.git -r 2.x

Then, generate the comment model and migration with script/generate comment and migrate the database with rake db:migrate

The tricky bit is nesting comments under other resources in a polymorphic way. Here is what I did:

# In config/routes.rb
map.resources :comments, :path_prefix => '/:commentable_type/:commentable_id'


# In app/controllers/comments_controller.rb
before_filter :load_commentable
def create
  @comment = @commentable.comments.build(params[:comment])
  @comment.user = current_user
  respond_to do |format|
    if @comment.save
      format.html { redirect_to @commentable }
    else
      format.html { render :action => 'new' }
    end
  end
end

protected
def load_commentable
  @commentable = params[:commentable_type].camelize.constantize.find(params[:commentable_id])
end


# In app/views/comments/_form.html.erb
<%= form_for(:comment, :url => comments_path(commentable.class.to_s.underscore, commentable.id)) do |f| %>


# In app/views/model_that_allows_comments/show.html.erb
<%= render :partial => 'comments/form', :locals => {:commentable => @model_that_allows_comments} %>

I think that shows the relevant parts clearly enough to understand what is happening. It makes it possible to add acts_as_commentable to any model. You just have to pass in the commentable object in the locals hash when rendering the comments form and the same comments controller / view code should work.

Makoto
  • 104,088
  • 27
  • 192
  • 230
eksatx
  • 1,023
  • 2
  • 10
  • 15
  • i'm using acts as commentable with threading. there is no comments controller generated. I can't tell if it's necessary or not. – ahnbizcad Jun 02 '14 at 00:50
  • Wow, load_commentable should really be part of the gem. This is a better flow than the one from the gems documentation – light24bulbs Jun 05 '14 at 23:35
7

acts_as_commentable merely exposes you a Comment model and takes care of the plumbing between that model and your commentable models. It doesn't give you any controllers or views. You are responsible for deciding how you want to implement this part of your application.

It is pretty straightforward, though. For example...

# in routes.rb
map.resources :posts, :has_many => :comments

# in your comments controller...
class CommentsController < ApplicationController
  before_filter :get_post

  def get_post
    @post = Post.find(params[:post_id])
  end

  def index
    @comments = @post.comments.all # or sorted by date, or paginated, etc.
  end
end

# In your haml view...
%h1== Comments for #{@post.title}:
%ul
  - comments.each do |comment|
    %h3= comment.title
    %p= comment.comment

You'll see the comments for a particular post when you go to /posts/1/comments now.

Koen.
  • 25,449
  • 7
  • 83
  • 78
Dave Pirotte
  • 3,806
  • 21
  • 14
  • 1
    Thanks for the answer, although your example ties comments to posts. It seems like that defeats the purpose of the polymorphic association acts_as_commentable uses. I assume this is intended to let you attach comments to numerous models. – eksatx Sep 18 '10 at 22:03
  • 1
    Yes, you can attach to multiple different models. See my response here: http://stackoverflow.com/questions/3653263/rails-nesting-resource-with-two-parents/3653391#3653391. The *easiest* way to support multiple parent models is to use something like inherited_resources. – Dave Pirotte Sep 18 '10 at 22:18
  • 1
    Well, heck. I think inherited_resources would have saved me some keystrokes (see the answer I posted above). – eksatx Sep 18 '10 at 22:24
2

I think the best way to add comments to any model is creating a method called comment in your ApplicationController.rb file like this.

def comment 
  # Extracts the name of the class
  klass = self.class.to_s[/\A(\w+)sController\Z/,1] 
  # Evaluates the class and gets the current object of that class
  @comentable_class = eval "#{klass}.find(params[:id])"
  # Creates a comment using the data of the form
  comment = Comment.new(params[:comment])
  # Adds the comment to that instance of the class
  @comentable_class.add_comment(comment)

  flash[:notice] = "Your comment has been added!"
  redirect_to :action => "show", :id => params[:id] 
end    

and then just create some partial _comment.rb to use it in any model you want

<%= form_tag :action => "comment", :id => Your_model_goes_here %>
  <p><label for="comment_title">Title</label><br/>
  <%= text_field 'comment', 'title' %></p>
  <%= text_area "comment", "comment", :rows => 5, :cols => 50 %> <br />
  <%= submit_tag "Comment!.." %>
</form>

I hope it's useful for someone...

Dan
  • 21
  • 1