Acts_as_commentable release

I now have the acts_as_commentable plugin up on RubyForge. This
plugin will allow you to add comments to any active_record object in
your Rails application.

So far the directions are simple, and there are only a few features:

To install:
ruby script/plugin install
svn://rubyforge.org//var/svn/commentable/acts_as_commentable

In the readme there is a sample migration you will need to use, with
directions on how to modify it if need be. I’m still learning how the
plugins work, and do not know if there is a way to autogenerate this.

Once the migration is completed and ran, you can just add:
acts_as_commentable to those objects you want to comment on and you’re
all set.

Lets say you have a Person object:

class Person < ActiveRecord::Base
acts_as_commentable
end

Then you have a person:

p = Person.find(:first)

Create a comment:

c = Comment.new

Fill out the comment

c.name = “Name of Commentor”
c.content = “What they wrote”

then add it to your object:

p.add_comment©

to remove a comment:

p.remove_comment©

I think that’s everything. This was done quick and dirty, If there
are things you would like to see in this, let me know. I don’t know
if there is much more to do that wouldn’t be application specific.

Thanks
Josh

Published at http://agilewebdevelopment.com/plugins/
acts_as_commentable :slight_smile:


Benjamin C.
http://www.tesly.com/ – Collaborative test case management
http://www.agilewebdevelopment.com/ – Resources for the Rails community

Josh,
Thank you for this wonderful plugin. Exactly what I need. Unfortunately,
as a noobie, I don’t know how to put the parts together.

First, should there be a comment_controller and a comment.rb model?

Lets say you have a Person object:

class Person < ActiveRecord::Base
acts_as_commentable
end

Ok, I’ve done that.

Then you have a person:

p = Person.find(:first)

Create a comment:

c = Comment.new

I’d like to put the capability to add a comment to a person instance
during Create, Edit, and Show of a person instance. Where do I put this
command: c = Comment.new? Which controller? Which action?

Fill out the comment

c.name = “Name of Commentor”
c.content = “What they wrote”

This filling out of the comment should happen in a New.rhtml comment
view, right?

then add it to your object:

p.add_comment©

to remove a comment:

p.remove_comment©

The above must be done in a Create and Destory action in the
comment_controller, right?

I apologize for these jumbo dumbo questions. I’m just beginning to get a
feel for the broad strokes; the massive details still elude me.

Thanks,
gk

Hi Gene,
It uses a polymorphic association. The commentable_id and type work as
you thoguht tahy did. You can find mor about polymorphic associations
in rails on the wiki.

Chris.

Gene K. wrote:

Hi,

The data table supporting acts_as_commentable has the following
definition:

def self.up
create_table “comments”, :force => true do |t|
t.column “title”, :string, :limit => 50, :default => “”
t.column “comment”, :string, :default => “”
t.column “created_at”, :datetime, :null => false
t.column “commentable_id”, :integer, :default => 0, :null => false
t.column “commentable_type”, :string, :limit => 15, :default =>
“”, :null => false
t.column “user_id”, :integer, :default => 0, :null => false
end

What do the columns “commentable_id” and “commentable_type” function as?
Would commentable_id be the id of the instance of the object being
commented on, and commentable_type be the name of its class?

Thanks again,
gk

Hi,

The data table supporting acts_as_commentable has the following
definition:

def self.up
create_table “comments”, :force => true do |t|
t.column “title”, :string, :limit => 50, :default => “”
t.column “comment”, :string, :default => “”
t.column “created_at”, :datetime, :null => false
t.column “commentable_id”, :integer, :default => 0, :null => false
t.column “commentable_type”, :string, :limit => 15, :default =>
“”, :null => false
t.column “user_id”, :integer, :default => 0, :null => false
end

What do the columns “commentable_id” and “commentable_type” function as?
Would commentable_id be the id of the instance of the object being
commented on, and commentable_type be the name of its class?

Thanks again,
gk

Chris C. wrote:

Hi Gene,
It uses a polymorphic association. The commentable_id and type work as
you thoguht tahy did. You can find mor about polymorphic associations
in rails on the wiki.

Chris.

Gene K. wrote:

Hi,

The data table supporting acts_as_commentable has the following
definition:

def self.up
create_table “comments”, :force => true do |t|
t.column “title”, :string, :limit => 50, :default => “”
t.column “comment”, :string, :default => “”
t.column “created_at”, :datetime, :null => false
t.column “commentable_id”, :integer, :default => 0, :null => false
t.column “commentable_type”, :string, :limit => 15, :default =>
“”, :null => false
t.column “user_id”, :integer, :default => 0, :null => false
end

What do the columns “commentable_id” and “commentable_type” function as?
Would commentable_id be the id of the instance of the object being
commented on, and commentable_type be the name of its class?

Thanks again,
gk

Hi, Chris,
So then one can pull out easily from a single table comments about an
instance, about all instances of a class, by a user, or list comments in
descending date (“Recent Comments”) order. Great! Just what I want.
Thanks for the tip on poly; I’ll pursue.
gk

hello,
if i have a post that acts as commentable and i need to find all
comments relating to the post, do i just add the post id to the comments
table, and just do a comments.find :all, :condition where post.id ==
post_id ??

koloa wrote:

hello,
if i have a post that acts as commentable and i need to find all
comments relating to the post, do i just add the post id to the comments
table, and just do a comments.find :all, :condition where post.id ==
post_id ??

the easiest would be to do:
@post = Post.find(params[:id])
@comments = @post.comments

That will give you only comments for that post.

(unless the associations are different)

–jake

hello i have a question,

in the directions at
http://www.juixe.com/techknow/index.php/2006/06/18/acts-as-commentable-plugin
it states that there must be a user model? since i am applying
acts_as_commentable to a recipe, do i change the user_id in the comments
table to a recipe_id?

also, i am receiving this error

Mysql::Error: #42S02Table ‘howtodb.commentings’ doesn’t exist: SHOW
FIELDS FROM commentings

my database name is howtodb, my application name is called howto, and i
have a table called howto which is the model that is acting like a
comments.

thanks for any help!

also i notice this…

in the webpage, the migration table is this

def self.up
create_table :comments, :force => true do |t|
t.column :title, :string, :limit => 50, :default => “”
t.column :comment, :string, :default => “”
t.column :created_at, :datetime, :null => false
t.column :commentable_id, :integer, :default => 0, :null => false
t.column :commentable_type, :string, :limit => 15,
:default => “”, :null => false
t.column :user_id, :integer, :default => 0, :null => false
end

add_index :comments, [“user_id”], :name => “fk_comments_user”
end

def self.down
drop_table :comments
end

in the readmen file the migration table is this:
def self.up
create_table :commentings do |t|
t.column :commentable_id, :integer
t.column :comment_id, :integer
t.column :commentable_type, :string
end
create_table :comments do |t|
t.column :name, :string
t.column :content, :text
end
end

def self.down
drop_table :commentings
drop_table :comments
end

there is suppose to be a commenting table?

You (the user) are adding comments to the recipe, so
acts_as_commentable expects a table called “user” with an id field.
There is no need to change the tables as the association is polymorphic
(it can apply to any model), hence the commentable_type and
commentable_id fields.

My README file defines a comments table - not sure where you are
getting the commentings from…

How are you calling up the comments to produce that error?

hello, everything seems to be working now after i generated the
commenting table.

did i do this correctly since the webpage i read didnt have anything for
the commentings table in the migration?

hello askegg! thanks for helping…

here is what the readme says:

def self.up
create_table :commentings do |t|
t.column :commentable_id, :integer
t.column :comment_id, :integer
t.column :commentable_type, :string
end
create_table :comments do |t|
t.column :name, :string
t.column :content, :text
end
end

def self.down
drop_table :commentings
drop_table :comments
end

here is what i originaly only had for acts_as_commentable

def self.up
create_table :comments, :force => true do |t|
t.column :title, :string, :limit => 50, :default => “”
t.column :comment, :string, :default => “”
t.column :created_at, :datetime, :null => false
t.column :commentable_id, :integer, :default => 0, :null =>
false
t.column :commentable_type, :string, :limit => 15,
:default => “”, :null => false
t.column :user_id, :integer, :default => 0, :null => false
end

  add_index :comments, ["user_id"], :name => "fk_comments_user"
end

i can do this in my controller just fine…
@asset = Howto.find(1)
comment = Comment.new(:title => “title!!!”, :comment => “some silly
comment,…”)
logger << “COMMENT #{comment.comment}n”
@asset.add_comment comment

and when i check for the information in the comments and the commentings
table, the information is there.

but when i do this to pass the information to a getDetail view page

@howto = Howto.getHowto(params[:id])
@comments = @howto.comments

i get this error… undefined method `comments’ for #Array:0x22bab08

and when i do a debug(@howto)

i do not see the relationship between my Howto model and acts as
commentable…

i have a user table from acts as authenticated…could that cause an
issue?

do i need to add a belongs_to :howto in the comment.rb file?

Thanks for any help!!!

i have reinstalled from original source from above…but when executing
@howto.add_comment©, i am getting method not found.

do i need to modify the comment.rb file to put the belongs_to howto
class?

Hmmm, the copy I have does not include any mention of a commentings
table - I think I can safely ignore it. Perhaps you should make sure
you have the latest version first?

The comments table schema looks exactly the same as mine. The usage in
the controller looks OK, but what does the getHowTo method in the HowTo
model do?

The relationship between the Howto model should be built by the plugin:

class Howto < ActiveRecord::Base
acts_as_commentable
end

So long as there is a user account with an id field, comments should be
happy. This should not really matter unless you are searching for
comments by a particular user.

You should not need to add anything to the comment.rb file as you are
not asking “which of all these comments belongs to this howto?” but
“Given this howto, what are the comments made?”. The difference is in
the direction of the question.

Do me a favor? First restart your webserver and view the page - it
might work. Then refresh the page without restarting (it might fail).
Repeat to make sure. There may be a bug in the plugin (I am
experiencing similar issues).

After that - have a look at your custom getHowto method and get back to
me.

Try it, but you shouldn’t need to.
The plugin adds the methods for you.

poipu wrote:

when i do this

@howto = Howto.find(id)

and print out the @howto via debug in my view, i dont see any
association to the acts_as_commentable. because of this i guess thats
the reason why @howto.add_comment© doesnt work…

No, you wont because the method find returns a Howto object, which does
not describe the methods available on the object. If you want to see
these, start a console (./scripts/console) and type:

howto=Howto.find(1)
howto.methods.sort

You should see add_comment listed…

hmmmm something odd or its working properly…

this works

@howto = Howto.find(params[:id])
c = Comment.new
c.name = "Name of Commentor"
c.content = "What they wrote"
@howto.add_comment c

but this doesnt

@howto = Howto.getHowto(params[:id])
c = Comment.new
c.name = "Name of Commentor"
c.content = "What they wrote"
@howto.add_comment c

where getHowto is a condition in my howto model class
def self.getHowto(id)
Howto.find(:all, :conditions => [“id = ?”, id])
end

is there a particular reason why using the bottom example does not
recognize add_comment method?

oh i see…thansk so much for taking the time to help and explain!
appreciate it! now time to work on creating that view…

but…is there a way to get a howto object without the comments? like a
.find( :dontinclude comments)

a little more info

this is my howto class

class Howto < ActiveRecord::Base

acts_as_commentable
acts_as_ferret :fields =>[“title”, “howto”, :main_category]
acts_as_rateable

has_many :howtophotos
belongs_to :scategory
belongs_to :user


basically i dont really care who the comments belong to since its the
public so i dont think ill ever need to search comments by user name…i
am just looking for a way to say…

get my howto and display all the associated comments and give a form so
other people can attach their comments to the howto article.

when i do this

@howto = Howto.find(id)

and print out the @howto via debug in my view, i dont see any
association to the acts_as_commentable. because of this i guess thats
the reason why @howto.add_comment© doesnt work…

hmmmm