Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a clean approach to implement acts_as_commentable in a Rails application?

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.

like image 428
eksatx Avatar asked Sep 18 '10 00:09

eksatx


2 Answers

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.

like image 161
eksatx Avatar answered Oct 07 '22 00:10

eksatx


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.

like image 23
Dave Pirotte Avatar answered Oct 06 '22 23:10

Dave Pirotte