Skip to content
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Usage

@article = Article.find(params[:id])
@user_who_commented = @current_user
@comment = Comment.build_from( @article, @user_who_commented.id, "Hey guys this is my comment!" )
@comment = Comment.build_from( @article, @user_who_commented, "Hey guys this is my comment!" )

* To make a newly created comment into a child/reply of another comment:

Expand Down
7 changes: 3 additions & 4 deletions lib/acts_as_commentable_with_threading.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ def find_comments_for(obj)
# Helper class method to lookup comments for
# the mixin commentable type written by a given user.
# This method is NOT equivalent to Comment.find_comments_for_user
def find_comments_by_user(user)
commentable = base_class.name.to_s
Comment.where(user_id: user.id, commentable_type: commentable)
.order('created_at DESC')
def find_comments_by_commenter(commenter)
commentable = self.base_class.name.to_s
Comment.where(commenter_id: commenter.id, commenter_type: commenter.class.to_s, commentable_type: commentable).order('created_at DESC')
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@ class Comment < ActiveRecord::Base
acts_as_nested_set scope: [:commentable_id, :commentable_type]

validates :body, presence: true
validates :user, presence: true
validates :commenter, presence: true

# NOTE: install the acts_as_votable plugin if you
# want user to vote on the quality of comments.
# acts_as_votable
# want commenter to vote on the quality of comments.
#acts_as_votable

belongs_to :commentable, polymorphic: true

# NOTE: Comments belong to a user
belongs_to :user
# NOTE: Comments belong to a commenter
belongs_to :commenter, :polymorphic => true

# Helper class method that allows you to build a comment
# by passing a commentable object, a user_id, and comment text
# by passing a commentable object, a commenter object, and comment text
# example in readme
def self.build_from(obj, user_id, comment)
def self.build_from(obj, commenter, comment)
new \
commentable: obj,
body: comment,
user_id: user_id
commentable: obj,
body: comment,
commenter: commenter
end

# helper method to check if a comment has children
def has_children?
children.size > 0
!self.children.empty?
end

# Helper class method to lookup all comments assigned
# to all commentable types for a given user.
scope :find_comments_by_user, lambda { |user|
where(user_id: user.id).order('created_at DESC')
# to all commentable types for a given commenter.
scope :find_comments_by_commenter, lambda { |commenter|
where(commenter_id: commenter.id, commenter_type: commenter.class.to_s).order('created_at DESC')
}

# Helper class method to look up all comments for
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
class ActsAsCommentableUpgradeMigration < ActiveRecord::Migration
def self.up
rename_column :comments, :comment, :body
add_column :comments, :subject, :string
add_column :comments, :parent_id, :integer
add_column :comments, :lft, :integer
add_column :comments, :rgt, :integer
add_column :comments, :updated_at, :datetime
add_column :comments, :subject, :string
add_column :comments, :parent_id, :integer
add_column :comments, :lft, :integer
add_column :comments, :rgt, :integer
add_column :comments, :updated_at, :datetime
add_column :comments, :commenter_id, :integer
add_column :comments, :commenter_type, :string
remove_column :comments, :updated_at
remove_column :comments, :user_id
remove_column :comments, :user_type


add_index :comments, :commentable_id
add_index :comments, :commentable_id
add_index :comments, :commenter_id
remove_index :comments, :user_id
end

def self.down
Expand All @@ -17,7 +25,15 @@ def self.down
remove_column :comments, :lft
remove_column :comments, :rgt
remove_column :comments, :updated_at

remove_index :comments, :commentable_id
remove_column :comments, :commenter_id, :integer
remove_column :comments, :commenter_type, :string

add_column :comments, :user_id, :integer
add_column :comments, :user_type, :string

remove_index :comments, :commenter_id
remove_index :comments, :commentable_id

add_index :comments, :user_id
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ class Comment < ActiveRecord::Base
acts_as_nested_set scope: [:commentable_id, :commentable_type]

validates :body, presence: true
validates :user, presence: true
validates :commenter, presence: true

# NOTE: install the acts_as_votable plugin if you
# want user to vote on the quality of comments.
# acts_as_votable
# want commenter to vote on the quality of comments.
#acts_as_votable

belongs_to :commentable, polymorphic: true

# NOTE: Comments belong to a user
belongs_to :user
# NOTE: Comments belong to a commenter
belongs_to :commenter, :polymorphic => true

# Helper class method that allows you to build a comment
# by passing a commentable object, a user_id, and comment text
# by passing a commentable object, a commenter object, and comment text
# example in readme
def self.build_from(obj, user_id, comment)
def self.build_from(obj, commenter, comment)
new \
commentable: obj,
body: comment,
user_id: user_id
body: comment,
commenter: commenter
end

# helper method to check if a comment has children
Expand All @@ -29,9 +29,9 @@ def has_children?
end

# Helper class method to lookup all comments assigned
# to all commentable types for a given user.
scope :find_comments_by_user, lambda { |user|
where(user_id: user.id).order('created_at DESC')
# to all commentable types for a given commenter.
scope :find_comments_by_commenter, lambda { |commenter|
where(commenter_id: commenter.id, commenter_type: commenter.class.to_s).order('created_at DESC')
}

# Helper class method to look up all comments for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ def self.up
t.string :title
t.text :body
t.string :subject
t.integer :user_id, null: false
t.references :commenter, :polymorphic => true
t.integer :parent_id, :lft, :rgt
t.timestamps
end

add_index :comments, :user_id

add_index :comments, [:commentable_id, :commentable_type]
add_index :comments, [:commenter_id, :commenter_type]
end

def self.down
Expand Down
52 changes: 24 additions & 28 deletions spec/comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
describe Comment do
before do
@user = User.create!
@comment = Comment.create!(body: 'Root comment', user: @user)
@comment = Comment.create!(body: "Root comment", commenter: @user)
end

describe 'that is valid' do
it 'should have a user' do
expect(@comment.user).not_to be_nil
describe "that is valid" do
it "should have a user" do
expect(@comment.commenter).not_to be_nil
end

it 'should have a body' do
Expand All @@ -26,16 +26,16 @@
expect(@comment.children.size).to eq(0)
end

it 'can add child Comments' do
grandchild = Comment.new(body: 'This is a grandchild', user: @user)
it "can add child Comments" do
grandchild = Comment.new(body: "This is a grandchild", commenter: @user)
grandchild.save!
grandchild.move_to_child_of(@comment)
expect(@comment.children.size).to eq(1)
end

describe 'after having a child added' do
before do
@child = Comment.create!(body: 'Child comment', user: @user)
@child = Comment.create!(body: "Child comment", commenter: @user)
@child.move_to_child_of(@comment)
end

Expand All @@ -48,14 +48,13 @@
end
end

describe 'finders' do
describe '#find_comments_by_user' do
describe "finders" do
describe "#find_comments_by_commenter" do
before :each do
@other_user = User.create!
@user_comment = Comment.create!(body: 'Child comment', user: @user)
@non_user_comment = Comment.create!(body: 'Child comment',
user: @other_user)
@comments = Comment.find_comments_by_user(@user)
@user_comment = Comment.create!(body: "Child comment", commenter: @user)
@non_user_comment = Comment.create!(body: "Child comment", commenter: @other_user)
@comments = Comment.find_comments_by_commenter(@user)
end

it 'should return all the comments created by the passed user' do
Expand All @@ -70,21 +69,18 @@
describe '#find_comments_for_commentable' do
before :each do
@other_user = User.create!
@user_comment =
Comment.create!(body: 'from user',
commentable_type: @other_user.class.to_s,
commentable_id: @other_user.id,
user: @user)

@other_comment =
Comment.create!(body: 'from other user',
commentable_type: @user.class.to_s,
commentable_id: @user.id,
user: @other_user)

@comments =
Comment.find_comments_for_commentable(@other_user.class,
@other_user.id)
@user_comment = Comment.create!(body: 'from user',
commentable_type: @other_user.class.to_s,
commentable_id: @other_user.id,
commenter: @user)

@other_comment = Comment.create!(body: 'from other user',
commentable_type: @user.class.to_s,
commentable_id: @user.id,
commenter: @other_user)

@comments = Comment.find_comments_for_commentable(@other_user.class,
@other_user)
end

it 'should return the comments for the passed commentable' do
Expand Down
42 changes: 16 additions & 26 deletions spec/commentable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
before :each do
@user = User.create!
@commentable = Commentable.create!
@comment = Comment.create!(user: @user,
@comment = Comment.create!(commenter: @user,
commentable: @commentable,
body: 'blargh')
end
Expand All @@ -19,10 +19,10 @@
expect(Comment.all).not_to include(@comment)
end

it 'also destroys its nested comments' do
child = Comment.new(body: 'This is a child',
it "also destroys its nested comments" do
child = Comment.new(body: "This is a child",
commentable: @commentable,
user: @user)
commenter: @user)
child.save!
child.move_to_child_of(@comment)

Expand All @@ -41,11 +41,11 @@

describe '#find_comments_for' do
before :each do
@comment = Comment.create!(user: @user,
@comment = Comment.create!(commenter: @user,
commentable: @commentable,
body: 'blargh')

@other_comment = Comment.create!(user: @user,
@other_comment = Comment.create!(commenter: @user,
commentable: @other_commentable,
body: 'hello')

Expand All @@ -61,27 +61,27 @@
end
end

describe '#find_comments_by_user' do
describe "#find_comments_by_commenter" do
before :each do
@user2 = User.create!

@comment = Comment.create!(user: @user,
@comment = Comment.create!(commenter: @user,
commentable: @commentable,
body: 'blargh')

@other_comment = Comment.create!(user: @user2,
@other_comment = Comment.create!(commenter: @user2,
commentable: @other_commentable,
body: 'hello')

@comments = Commentable.find_comments_by_user(@user)
@comments = Commentable.find_comments_by_commenter(@user)
end

it 'should return comments by the passed user' do
expect(@comments.all? { |c| c.user == @user }).to eq(true)
expect(@comments.all? { |c| c.commenter == @user }).to eq(true)
end

it 'should not return comments by other users' do
expect(@comments.any? { |c| c.user != @user }).to eq(false)
expect(@comments.any? { |c| c.commenter != @user }).to eq(false)
end
end
end
Expand All @@ -92,20 +92,10 @@
@user = User.create!
@commentable = Commentable.create!
@other_commentable = Commentable.create!
@comment = Comment.create!(user: @user,
commentable: @commentable,
body: 'sup')
@older_comment = Comment.create!(user: @user,
commentable: @commentable,
body: 'sup',
created_at: 1.week.ago)
@oldest_comment = Comment.create!(user: @user,
commentable: @commentable,
body: 'sup',
created_at: 2.years.ago)
@other_comment = Comment.create!(user: @user,
commentable: @other_commentable,
body: 'sup')
@comment = Comment.create!(commenter: @user, commentable: @commentable, body: 'sup')
@older_comment = Comment.create!(commenter: @user, commentable: @commentable, body: 'sup', created_at: 1.week.ago)
@oldest_comment = Comment.create!(commenter: @user, commentable: @commentable, body: 'sup', created_at: 2.years.ago)
@other_comment = Comment.create!(commenter: @user, commentable: @other_commentable, body: 'sup')
@comments = @commentable.comments_ordered_by_submitted
end

Expand Down
Loading