acts_as_commentable_with_threading 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/CHANGELOG +22 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +82 -0
- data/MIT-LICENSE +20 -0
- data/README.md +98 -0
- data/Rakefile +29 -0
- data/acts_as_commentable_with_threading.gemspec +22 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/acts_as_commentable_with_threading.rb +64 -0
- data/lib/generators/acts_as_commentable_upgrade_migration/USAGE +5 -0
- data/lib/generators/acts_as_commentable_upgrade_migration/acts_as_commentable_upgrade_migration_generator.rb +19 -0
- data/lib/generators/acts_as_commentable_upgrade_migration/comment.rb +48 -0
- data/lib/generators/acts_as_commentable_upgrade_migration/templates/migration.rb +23 -0
- data/lib/generators/acts_as_commentable_with_threading_migration/USAGE +5 -0
- data/lib/generators/acts_as_commentable_with_threading_migration/acts_as_commentable_with_threading_migration_generator.rb +19 -0
- data/lib/generators/acts_as_commentable_with_threading_migration/templates/comment.rb +48 -0
- data/lib/generators/acts_as_commentable_with_threading_migration/templates/migration.rb +21 -0
- data/rails/init.rb +6 -0
- data/spec/comment_spec.rb +87 -0
- data/spec/commentable_spec.rb +78 -0
- data/spec/db/database.yml +18 -0
- data/spec/db/schema.rb +25 -0
- data/spec/spec_helper.rb +24 -0
- metadata +214 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
v0.1.0
|
2
|
+
------
|
3
|
+
Initial Release
|
4
|
+
|
5
|
+
v0.1.1
|
6
|
+
------
|
7
|
+
Fixes to gemspec
|
8
|
+
|
9
|
+
v0.1.2
|
10
|
+
------
|
11
|
+
|
12
|
+
Added new documentation in README that should better help users understand this plugin
|
13
|
+
Added new instance method "root_comments" that will return all comments belonging to a model except child comments
|
14
|
+
Added new class method for Comment: "self.build_from(object, user_id, comment_text:string)"
|
15
|
+
- This method cleans up the code inside the controllers.
|
16
|
+
Added new class method for Comment: "has_children?" that will return true or false depending on if a comment has children
|
17
|
+
Updated deprecated code in instance method "comments_ordered_by_submitted"
|
18
|
+
- changed "self.type.name" to "self.class.name"
|
19
|
+
|
20
|
+
v0.1.2
|
21
|
+
|
22
|
+
fixed a problem that arises when trying to use the acts_as_voteable plugin with your comments
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Generated from /Users/light/work/my/acts_as_commentable_with_threading/acts_as_commentable_with_threading.gemspec
|
2
|
+
source :gemcutter
|
3
|
+
gem "activerecord", "~> 3.0"
|
4
|
+
gem "activesupport", "~> 3.0"
|
5
|
+
gem "moretea-awesome_nested_set", ">= 0"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "rake", ">= 0"
|
9
|
+
gem "bundler", "~> 1.0"
|
10
|
+
gem "rspec", "~> 1.3"
|
11
|
+
gem "sqlite3-ruby", ">= 0"
|
12
|
+
gem "rails", "~> 3.0"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionmailer (3.0.0)
|
6
|
+
actionpack (= 3.0.0)
|
7
|
+
mail (~> 2.2.5)
|
8
|
+
actionpack (3.0.0)
|
9
|
+
activemodel (= 3.0.0)
|
10
|
+
activesupport (= 3.0.0)
|
11
|
+
builder (~> 2.1.2)
|
12
|
+
erubis (~> 2.6.6)
|
13
|
+
i18n (~> 0.4.1)
|
14
|
+
rack (~> 1.2.1)
|
15
|
+
rack-mount (~> 0.6.12)
|
16
|
+
rack-test (~> 0.5.4)
|
17
|
+
tzinfo (~> 0.3.23)
|
18
|
+
activemodel (3.0.0)
|
19
|
+
activesupport (= 3.0.0)
|
20
|
+
builder (~> 2.1.2)
|
21
|
+
i18n (~> 0.4.1)
|
22
|
+
activerecord (3.0.0)
|
23
|
+
activemodel (= 3.0.0)
|
24
|
+
activesupport (= 3.0.0)
|
25
|
+
arel (~> 1.0.0)
|
26
|
+
tzinfo (~> 0.3.23)
|
27
|
+
activeresource (3.0.0)
|
28
|
+
activemodel (= 3.0.0)
|
29
|
+
activesupport (= 3.0.0)
|
30
|
+
activesupport (3.0.0)
|
31
|
+
arel (1.0.1)
|
32
|
+
activesupport (~> 3.0.0)
|
33
|
+
builder (2.1.2)
|
34
|
+
erubis (2.6.6)
|
35
|
+
abstract (>= 1.0.0)
|
36
|
+
i18n (0.4.1)
|
37
|
+
mail (2.2.6.1)
|
38
|
+
activesupport (>= 2.3.6)
|
39
|
+
mime-types
|
40
|
+
treetop (>= 1.4.5)
|
41
|
+
mime-types (1.16)
|
42
|
+
moretea-awesome_nested_set (1.4.3.1)
|
43
|
+
activerecord (~> 3.0.0)
|
44
|
+
polyglot (0.3.1)
|
45
|
+
rack (1.2.1)
|
46
|
+
rack-mount (0.6.13)
|
47
|
+
rack (>= 1.0.0)
|
48
|
+
rack-test (0.5.5)
|
49
|
+
rack (>= 1.0)
|
50
|
+
rails (3.0.0)
|
51
|
+
actionmailer (= 3.0.0)
|
52
|
+
actionpack (= 3.0.0)
|
53
|
+
activerecord (= 3.0.0)
|
54
|
+
activeresource (= 3.0.0)
|
55
|
+
activesupport (= 3.0.0)
|
56
|
+
bundler (~> 1.0.0)
|
57
|
+
railties (= 3.0.0)
|
58
|
+
railties (3.0.0)
|
59
|
+
actionpack (= 3.0.0)
|
60
|
+
activesupport (= 3.0.0)
|
61
|
+
rake (>= 0.8.4)
|
62
|
+
thor (~> 0.14.0)
|
63
|
+
rake (0.8.7)
|
64
|
+
rspec (1.3.0)
|
65
|
+
sqlite3-ruby (1.3.1)
|
66
|
+
thor (0.14.2)
|
67
|
+
treetop (1.4.8)
|
68
|
+
polyglot (>= 0.3.1)
|
69
|
+
tzinfo (0.3.23)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
activerecord (~> 3.0)
|
76
|
+
activesupport (~> 3.0)
|
77
|
+
bundler (~> 1.0)
|
78
|
+
moretea-awesome_nested_set
|
79
|
+
rails (~> 3.0)
|
80
|
+
rake
|
81
|
+
rspec (~> 1.3)
|
82
|
+
sqlite3-ruby
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Evan David Light
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
Acts As Commentable (now with comment threads (TM)!!! -- kidding on the (TM))
|
2
|
+
===================
|
3
|
+
|
4
|
+
Allows for threaded comments to be added to multiple and different models. Drop-in compatible for acts_as_commentable (however requiring a database schema change)
|
5
|
+
|
6
|
+
Requirements
|
7
|
+
------------
|
8
|
+
|
9
|
+
This gem is for Rails 3 and later versions only.
|
10
|
+
|
11
|
+
This gem depends on [moretea's version](http://github.com/moretea/awesome_nested_set) of CollectiveIdea's Awesome Nested Set gem. It is installed if not already present when you install this gem.
|
12
|
+
|
13
|
+
You can find the gem on GitHub at [http://github.com/moretea/awesome_nested_set](http://github.com/moretea/awesome_nested_set).
|
14
|
+
|
15
|
+
Install
|
16
|
+
-------
|
17
|
+
|
18
|
+
In your Gemfile, add
|
19
|
+
gem 'acts_as_commentable_with_threading', :git => 'http://github.com/elight/acts_as_commentable_with_threading.git'
|
20
|
+
|
21
|
+
and run `bundle install`.
|
22
|
+
|
23
|
+
Migrations
|
24
|
+
----------
|
25
|
+
|
26
|
+
* To install from scratch:
|
27
|
+
|
28
|
+
`rails generate acts_as_commentable_with_threading_migration`
|
29
|
+
|
30
|
+
This will generate the migration script necessary for the table
|
31
|
+
|
32
|
+
* To upgrade to acts_as_commentable_with_threading from the old acts_as_commentable:
|
33
|
+
|
34
|
+
`rails generate acts_as_commentable_upgrade_migration`
|
35
|
+
|
36
|
+
This will generate the necessary migration to upgrade your comments table to work with acts_as_commentable_with_threading
|
37
|
+
|
38
|
+
If the generators fail, you can just as easily create the migrations by hand. See the templates in the generators under `lib/generators`.
|
39
|
+
|
40
|
+
Usage
|
41
|
+
-----
|
42
|
+
class Article < ActiveRecord::Base
|
43
|
+
acts_as_commentable
|
44
|
+
end
|
45
|
+
|
46
|
+
* Add a comment to a model instance, for example an Article
|
47
|
+
|
48
|
+
@article = Article.find(params[:id])
|
49
|
+
@user_who_commented = @current_user
|
50
|
+
@comment = Comment.build_from(@article, @user_who_commented.id, "Hey guys this is my comment!" )
|
51
|
+
|
52
|
+
* To make a newly created comment into a child/reply of another comment
|
53
|
+
|
54
|
+
comment.move_to_child_of(the_desired_parent_comment)
|
55
|
+
|
56
|
+
* To retrieve all comments for an article, including child comments
|
57
|
+
|
58
|
+
@all_comments = @article.comment_threads
|
59
|
+
|
60
|
+
* To retrieve only the root comments without their children comments
|
61
|
+
|
62
|
+
@root_comments = @article.root_comments
|
63
|
+
|
64
|
+
* To check if a comment has children
|
65
|
+
|
66
|
+
@comment.has_children?
|
67
|
+
|
68
|
+
* To verify the number of children a comment has
|
69
|
+
|
70
|
+
@comment.children.size
|
71
|
+
|
72
|
+
* To retrieve a comments children
|
73
|
+
|
74
|
+
@comment.children
|
75
|
+
|
76
|
+
|
77
|
+
*If you plan to use the acts_as_voteable plugin with your comment system be sure to uncomment two things:
|
78
|
+
|
79
|
+
in `lib/comment.rb` uncomment the line `acts_as_voteable`
|
80
|
+
|
81
|
+
in `lib/acts_as_commentable_with_threading.rb` uncomment the line `include Juixe::Acts::Voteable` near the top
|
82
|
+
|
83
|
+
Credits
|
84
|
+
-------
|
85
|
+
xxx - For contributing the updates for Rails 3!
|
86
|
+
|
87
|
+
Jack Dempsey - This plugin/gem is heavily influenced/liberally borrowed/stole from acts_as_commentable
|
88
|
+
|
89
|
+
which in turn credits....
|
90
|
+
|
91
|
+
Xelipe - Because acts_as_commentable was heavily influenced by Acts As Taggable.
|
92
|
+
|
93
|
+
More
|
94
|
+
----
|
95
|
+
|
96
|
+
[http://tripledogdare.net](http://tripledogdare.net)
|
97
|
+
|
98
|
+
[http://evan.tiggerpalace.com](http://evan.tiggerpalace.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
require 'bundler/setup'
|
6
|
+
|
7
|
+
PLUGIN = "acts_as_commentable_with_threading"
|
8
|
+
NAME = "acts_as_commentable_with_threading"
|
9
|
+
GEM_VERSION = "1.0.0"
|
10
|
+
AUTHOR = "Evan Light"
|
11
|
+
EMAIL = "evan@tripledogdare.net"
|
12
|
+
SUMMARY = "Plugin/gem that provides threaded comment functionality"
|
13
|
+
|
14
|
+
load 'acts_as_commentable_with_threading.gemspec'
|
15
|
+
spec = ACTS_AS_COMMENTABLE_WITH_THREADING
|
16
|
+
|
17
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
18
|
+
pkg.gem_spec = spec
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Rake::SpecTask.new do |t|
|
22
|
+
t.spec_files = FileList['spec/**_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
task :install => [:package] do
|
26
|
+
sh %{sudo gem install pkg/#{NAME}-#{GEM_VERSION}}
|
27
|
+
end
|
28
|
+
|
29
|
+
task :default => :spec
|
@@ -0,0 +1,22 @@
|
|
1
|
+
ACTS_AS_COMMENTABLE_WITH_THREADING = Gem::Specification.new do |s|
|
2
|
+
s.name = "acts_as_commentable_with_threading"
|
3
|
+
s.version = "1.1.0"
|
4
|
+
s.date = "2011-12-02"
|
5
|
+
s.summary = "Polymorphic comments Rails gem - Rails 3+ only"
|
6
|
+
s.email = "evan@tripledogdare.net"
|
7
|
+
s.homepage = "http://github.com/elight/acts_as_commentable_with_threading"
|
8
|
+
s.description = "Polymorphic threaded comments Rails gem for Rails 3+"
|
9
|
+
s.authors = ["Evan Light", "Jack Dempsey", "Xelipe", "xxx"]
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.test_files = ["spec/commentable_spec.rb", "spec/comment_spec.rb", "spec/spec_helper.rb", "spec/db/database.yml", "spec/db/schema.rb"]
|
12
|
+
|
13
|
+
s.add_development_dependency 'rake'
|
14
|
+
s.add_development_dependency 'bundler', '~> 1.0'
|
15
|
+
s.add_development_dependency 'rspec', '~> 1.3'
|
16
|
+
s.add_development_dependency 'sqlite3-ruby'
|
17
|
+
s.add_development_dependency 'rails', '~> 3.0'
|
18
|
+
|
19
|
+
s.add_dependency 'activerecord', '~> 3.0'
|
20
|
+
s.add_dependency 'activesupport', '~> 3.0'
|
21
|
+
s.add_dependency 'moretea-awesome_nested_set'
|
22
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('./rails/init', File.dirname(__FILE__))
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'awesome_nested_set'
|
3
|
+
ActiveRecord::Base.class_eval do
|
4
|
+
include CollectiveIdea::Acts::NestedSet
|
5
|
+
#include Juixe::Acts::Voteable #<-- uncomment this if you have installed and wish to use the acts_as_voteable plugin
|
6
|
+
end
|
7
|
+
|
8
|
+
#
|
9
|
+
unless ActiveRecord::Base.respond_to?(:acts_as_nested_set)
|
10
|
+
ActiveRecord::Base.send(:include, CollectiveIdea::Acts::NestedSet::Base)
|
11
|
+
end
|
12
|
+
|
13
|
+
# ActsAsCommentableWithThreading
|
14
|
+
module Acts #:nodoc:
|
15
|
+
module CommentableWithThreading #:nodoc:
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def acts_as_commentable
|
20
|
+
has_many :comment_threads, :class_name => "Comment", :as => :commentable, :dependent => :destroy, :order => 'created_at ASC'
|
21
|
+
include Acts::CommentableWithThreading::LocalInstanceMethods
|
22
|
+
extend Acts::CommentableWithThreading::SingletonMethods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# This module contains class methods
|
27
|
+
module SingletonMethods
|
28
|
+
# Helper method to lookup for comments for a given object.
|
29
|
+
# This method is equivalent to obj.comments.
|
30
|
+
def find_comments_for(obj)
|
31
|
+
Comment.where(:commentable_id => obj.id, :commentable_type => obj.class).order('created_at DESC')
|
32
|
+
end
|
33
|
+
|
34
|
+
# Helper class method to lookup comments for
|
35
|
+
# the mixin commentable type written by a given user.
|
36
|
+
# This method is NOT equivalent to Comment.find_comments_for_user
|
37
|
+
def find_comments_by_user(user)
|
38
|
+
commentable = self.base_class.name.to_s
|
39
|
+
Comment.where(:user_id => user.id, :commentable_type => commentable).order('created_at DESC')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module LocalInstanceMethods
|
44
|
+
|
45
|
+
# Helper method to display only root threads, no children/replies
|
46
|
+
def root_comments
|
47
|
+
self.comment_threads.where(:parent_id => nil)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Helper method to sort comments by date
|
51
|
+
def comments_ordered_by_submitted
|
52
|
+
Comment.where(:commentable_id => id, :commentable_type => self.class.name).order('created_at DESC')
|
53
|
+
end
|
54
|
+
|
55
|
+
# Helper method that defaults the submitted time.
|
56
|
+
def add_comment(comment)
|
57
|
+
comments << comment
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
ActiveRecord::Base.send(:include, Acts::CommentableWithThreading)
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Description:
|
2
|
+
run rails generate acts_as_commentable_upgrade_migration
|
3
|
+
|
4
|
+
no need to specify any parameters after acts_as_commentable_upgrade_migration as the generator just creates a migration to update your existing comments table
|
5
|
+
the acts_as_commentable_upgrade_migration file will be created in db/migrate
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ActsAsCommentableUpgradeMigrationGenerator < Rails::Generators::Base
|
2
|
+
include Rails::Generators::Migration
|
3
|
+
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
# *for the life of me*, i can't figure out why this isn't implemented elsewhere.
|
7
|
+
def self.next_migration_number(dirname)
|
8
|
+
if ActiveRecord::Base.timestamped_migrations
|
9
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
10
|
+
else
|
11
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def manifest
|
16
|
+
migration_template 'migration.rb', 'db/migrate/acts_as_commentable_upgrade_migration'
|
17
|
+
copy_file 'comment.rb', 'app/models/comment.rb'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Comment < ActiveRecord::Base
|
2
|
+
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
|
3
|
+
|
4
|
+
validates_presence_of :body
|
5
|
+
validates_presence_of :user
|
6
|
+
|
7
|
+
# NOTE: install the acts_as_votable plugin if you
|
8
|
+
# want user to vote on the quality of comments.
|
9
|
+
#acts_as_voteable
|
10
|
+
|
11
|
+
# NOTE: Comments belong to a user
|
12
|
+
belongs_to :user
|
13
|
+
|
14
|
+
# Helper class method that allows you to build a comment
|
15
|
+
# by passing a commentable object, a user_id, and comment text
|
16
|
+
# example in readme
|
17
|
+
def self.build_from(obj, user_id, comment)
|
18
|
+
c = self.new
|
19
|
+
c.commentable_id = obj.id
|
20
|
+
c.commentable_type = obj.class.name
|
21
|
+
c.body = comment
|
22
|
+
c.user_id = user_id
|
23
|
+
c
|
24
|
+
end
|
25
|
+
|
26
|
+
#helper method to check if a comment has children
|
27
|
+
def has_children?
|
28
|
+
self.children.size > 0
|
29
|
+
end
|
30
|
+
|
31
|
+
# Helper class method to lookup all comments assigned
|
32
|
+
# to all commentable types for a given user.
|
33
|
+
scope :find_comments_by_user, lambda { |user|
|
34
|
+
where(:user_id => user.id).order('created_at DESC')
|
35
|
+
}
|
36
|
+
|
37
|
+
# Helper class method to look up all comments for
|
38
|
+
# commentable class name and commentable id.
|
39
|
+
scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
|
40
|
+
where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
|
41
|
+
}
|
42
|
+
|
43
|
+
# Helper class method to look up a commentable object
|
44
|
+
# given the commentable class name and id
|
45
|
+
def self.find_commentable(commentable_str, commentable_id)
|
46
|
+
commentable_str.constantize.find(commentable_id)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ActsAsCommentableUpgradeMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
rename_column :comments, :comment, :body
|
4
|
+
add_column :comments, :subject, :string
|
5
|
+
add_column :comments, :parent_id, :integer
|
6
|
+
add_column :comments, :lft, :integer
|
7
|
+
add_column :comments, :rgt, :integer
|
8
|
+
add_column :comments, :updated_at, :datetime
|
9
|
+
|
10
|
+
add_index :comments, :commentable_id
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
rename_column :comments, :body, :comment
|
15
|
+
remove_column :comments, :subject
|
16
|
+
remove_column :comments, :parent_id
|
17
|
+
remove_column :comments, :lft
|
18
|
+
remove_column :comments, :rgt
|
19
|
+
remove_column :comments, :updated_at
|
20
|
+
|
21
|
+
remove_index :comments, :commentable_id
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
Description:
|
2
|
+
run rails generate acts_as_commentable_with_threading_migration
|
3
|
+
|
4
|
+
no need to specify any parameters after acts_as_commentable_with_threading_migration as the plugin relies on the table being named "comments"
|
5
|
+
the acts_as_commentable_with_threading_migration file will be created in db/migrate
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ActsAsCommentableWithThreadingMigrationGenerator < Rails::Generators::Base
|
2
|
+
include Rails::Generators::Migration
|
3
|
+
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
# Complete wtf that this isn't provided elsewhere.
|
7
|
+
def self.next_migration_number(dirname)
|
8
|
+
if ActiveRecord::Base.timestamped_migrations
|
9
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
10
|
+
else
|
11
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def manifest
|
16
|
+
migration_template 'migration.rb', 'db/migrate/acts_as_commentable_with_threading_migration'
|
17
|
+
copy_file 'comment.rb', 'app/models/comment.rb'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Comment < ActiveRecord::Base
|
2
|
+
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
|
3
|
+
|
4
|
+
validates_presence_of :body
|
5
|
+
validates_presence_of :user
|
6
|
+
|
7
|
+
# NOTE: install the acts_as_votable plugin if you
|
8
|
+
# want user to vote on the quality of comments.
|
9
|
+
#acts_as_voteable
|
10
|
+
|
11
|
+
# NOTE: Comments belong to a user
|
12
|
+
belongs_to :user
|
13
|
+
|
14
|
+
# Helper class method that allows you to build a comment
|
15
|
+
# by passing a commentable object, a user_id, and comment text
|
16
|
+
# example in readme
|
17
|
+
def self.build_from(obj, user_id, comment)
|
18
|
+
c = self.new
|
19
|
+
c.commentable_id = obj.id
|
20
|
+
c.commentable_type = obj.class.name
|
21
|
+
c.body = comment
|
22
|
+
c.user_id = user_id
|
23
|
+
c
|
24
|
+
end
|
25
|
+
|
26
|
+
#helper method to check if a comment has children
|
27
|
+
def has_children?
|
28
|
+
self.children.size > 0
|
29
|
+
end
|
30
|
+
|
31
|
+
# Helper class method to lookup all comments assigned
|
32
|
+
# to all commentable types for a given user.
|
33
|
+
scope :find_comments_by_user, lambda { |user|
|
34
|
+
where(:user_id => user.id).order('created_at DESC')
|
35
|
+
}
|
36
|
+
|
37
|
+
# Helper class method to look up all comments for
|
38
|
+
# commentable class name and commentable id.
|
39
|
+
scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
|
40
|
+
where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
|
41
|
+
}
|
42
|
+
|
43
|
+
# Helper class method to look up a commentable object
|
44
|
+
# given the commentable class name and id
|
45
|
+
def self.find_commentable(commentable_str, commentable_id)
|
46
|
+
commentable_str.constantize.find(commentable_id)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ActsAsCommentableWithThreadingMigration < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :comments, :force => true do |t|
|
4
|
+
t.integer :commentable_id, :default => 0
|
5
|
+
t.string :commentable_type, :limit => 15, :default => ""
|
6
|
+
t.string :title, :default => ""
|
7
|
+
t.text :body, :default => ""
|
8
|
+
t.string :subject, :default => ""
|
9
|
+
t.integer :user_id, :default => 0, :null => false
|
10
|
+
t.integer :parent_id, :lft, :rgt
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :comments, :user_id
|
15
|
+
add_index :comments, :commentable_id
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :comments
|
20
|
+
end
|
21
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path('./spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
# Specs some of the behavior of awesome_nested_set although does so to demonstrate the use of this gem
|
4
|
+
describe Comment do
|
5
|
+
before do
|
6
|
+
@user = User.create!
|
7
|
+
@comment = Comment.create!(:body => "Root comment", :user => @user)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "that is valid" do
|
11
|
+
it "should have a user" do
|
12
|
+
@comment.user.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have a body" do
|
16
|
+
@comment.body.should_not be_nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not have a parent if it is a root Comment" do
|
21
|
+
@comment.parent.should be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can have see how child Comments it has" do
|
25
|
+
@comment.children.size.should == 0
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can add child Comments" do
|
29
|
+
grandchild = Comment.new(:body => "This is a grandchild", :user => @user)
|
30
|
+
grandchild.save!
|
31
|
+
grandchild.move_to_child_of(@comment)
|
32
|
+
@comment.children.size.should == 1
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "after having a child added" do
|
36
|
+
before do
|
37
|
+
@child = Comment.create!(:body => "Child comment", :user => @user)
|
38
|
+
@child.move_to_child_of(@comment)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "can be referenced by its child" do
|
42
|
+
@child.parent.should == @comment
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can see its child" do
|
46
|
+
@comment.children.first.should == @child
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "finders" do
|
51
|
+
describe "#find_comments_by_user" do
|
52
|
+
before :each do
|
53
|
+
@other_user = User.create!
|
54
|
+
@user_comment = Comment.create!(:body => "Child comment", :user => @user)
|
55
|
+
@non_user_comment = Comment.create!(:body => "Child comment", :user => @other_user)
|
56
|
+
@comments = Comment.find_comments_by_user(@user)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return all the comments created by the passed user" do
|
60
|
+
@comments.should include(@user_comment)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should not return comments created by non-passed users" do
|
64
|
+
@comments.should_not include(@non_user_comment)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#find_comments_for_commentable" do
|
69
|
+
before :each do
|
70
|
+
@other_user = User.create!
|
71
|
+
@user_comment = Comment.create!(:body => 'from user', :commentable_type => @other_user.class.to_s, :commentable_id => @other_user.id, :user => @user)
|
72
|
+
|
73
|
+
@other_comment = Comment.create!(:body => 'from other user', :commentable_type => @user.class.to_s, :commentable_id => @user.id, :user => @other_user)
|
74
|
+
|
75
|
+
@comments = Comment.find_comments_for_commentable(@other_user.class, @other_user.id)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return the comments for the passed commentable" do
|
79
|
+
@comments.should include(@user_comment)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not return the comments for non-passed commentables" do
|
83
|
+
@comments.should_not include(@other_comment)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path('./spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "A class that is commentable" do
|
4
|
+
it "can have many root comments" do
|
5
|
+
Commentable.new.comment_threads.should be_a_kind_of(Enumerable)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "special class finders" do
|
9
|
+
before :each do
|
10
|
+
@user = User.create!
|
11
|
+
@commentable = Commentable.create!
|
12
|
+
@other_commentable = Commentable.create!
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#find_comments_for" do
|
16
|
+
before :each do
|
17
|
+
@comment = Comment.create!(:user => @user, :commentable_type => @commentable.class, :commentable_id => @commentable.id, :body => 'blargh')
|
18
|
+
|
19
|
+
@other_comment = Comment.create!(:user => @user, :commentable_type => @other_commentable.class, :commentable_id => @other_commentable.id, :body => 'hello')
|
20
|
+
|
21
|
+
@comments = Commentable.find_comments_for(@commentable)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return the comments for the passed commentable" do
|
25
|
+
@comments.should include(@comment)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not return the comments for other commentables" do
|
29
|
+
@comments.should_not include(@other_comment)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#find_comments_by_user" do
|
34
|
+
before :each do
|
35
|
+
@user2 = User.create!
|
36
|
+
|
37
|
+
@comment = Comment.create!(:user => @user, :commentable_type => @commentable.class, :commentable_id => @commentable.id, :body => 'blargh')
|
38
|
+
|
39
|
+
@other_comment = Comment.create!(:user => @user2, :commentable_type => @other_commentable.class, :commentable_id => @other_commentable.id, :body => 'hello')
|
40
|
+
|
41
|
+
@comments = Commentable.find_comments_by_user(@user)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return comments by the passed user" do
|
45
|
+
@comments.all? { |c| c.user == @user }.should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
it "should not return comments by other users" do
|
50
|
+
@comments.any? { |c| c.user != @user }.should be_false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "instance methods" do
|
56
|
+
describe "#comments_ordered_by_submitted" do
|
57
|
+
before :each do
|
58
|
+
@user = User.create!
|
59
|
+
@commentable = Commentable.create!
|
60
|
+
@other_commentable = Commentable.create!
|
61
|
+
@comment = Comment.create!(:user => @user, :commentable_type => @commentable.class, :commentable_id => @commentable.id, :body => 'sup')
|
62
|
+
@older_comment = Comment.create!(:user => @user, :commentable_type => @commentable.class, :commentable_id => @commentable.id, :body => 'sup', :created_at => 1.week.ago)
|
63
|
+
@oldest_comment = Comment.create!(:user => @user, :commentable_type => @commentable.class, :commentable_id => @commentable.id, :body => 'sup', :created_at => 2.years.ago)
|
64
|
+
@other_comment = Comment.create!(:user => @user, :commentable_type => @other_commentable.class, :commentable_id => @other_commentable.id, :body => 'sup')
|
65
|
+
@comments = @commentable.comments_ordered_by_submitted
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return its own comments, ordered with the newest first" do
|
69
|
+
@comments.all? { |c| c.commentable_type == @commentable.class.to_s and c.commentable_id == @commentable.id }.should be_true
|
70
|
+
@comments.each_cons(2) { |c, c2| c.created_at.should > c2.created_at }
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not include comments for other commentables" do
|
74
|
+
@comments.any? { |c| c.commentable_type != @commentable.class.to_s or c.commentable_id != @commentable.id }.should be_false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
sqlite3:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: acts_as_commentable_with_threading.sqlite3.db
|
4
|
+
sqlite3mem:
|
5
|
+
:adapter: sqlite3
|
6
|
+
:database: ":memory:"
|
7
|
+
postgresql:
|
8
|
+
:adapter: postgresql
|
9
|
+
:username: postgres
|
10
|
+
:password: postgres
|
11
|
+
:database: acts_as_commentable_with_threading_plugin_test
|
12
|
+
:min_messages: ERROR
|
13
|
+
mysql:
|
14
|
+
:adapter: mysql
|
15
|
+
:host: localhost
|
16
|
+
:username: root
|
17
|
+
:password:
|
18
|
+
:database: acts_as_commentable_with_threading_plugin_test
|
data/spec/db/schema.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 0) do
|
2
|
+
create_table "users", :force => true do |t|
|
3
|
+
t.timestamps
|
4
|
+
end
|
5
|
+
|
6
|
+
create_table "commentables", :force => true do |t|
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
create_table "comments", :force => true do |t|
|
11
|
+
t.integer "commentable_id", :default => 0
|
12
|
+
t.string "commentable_type", :limit => 15, :default => ""
|
13
|
+
t.string "title", :default => ""
|
14
|
+
t.text "body", :default => ""
|
15
|
+
t.string "subject", :default => ""
|
16
|
+
t.integer "user_id", :default => 0, :null => false
|
17
|
+
t.integer "parent_id"
|
18
|
+
t.integer "lft"
|
19
|
+
t.integer "rgt"
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
add_index "comments", "user_id"
|
24
|
+
add_index "comments", "commentable_id"
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
plugin_test_dir = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
ActiveRecord::Base.logger = Logger.new(File.join(plugin_test_dir, "debug.log"))
|
8
|
+
|
9
|
+
ActiveRecord::Base.configurations = YAML::load_file(File.join(plugin_test_dir, "db", "database.yml"))
|
10
|
+
ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem")
|
11
|
+
ActiveRecord::Migration.verbose = false
|
12
|
+
load(File.join(plugin_test_dir, "db", "schema.rb"))
|
13
|
+
|
14
|
+
require File.join(plugin_test_dir, '..', 'init')
|
15
|
+
|
16
|
+
class User < ActiveRecord::Base
|
17
|
+
has_many :comments
|
18
|
+
end
|
19
|
+
|
20
|
+
class Commentable < ActiveRecord::Base
|
21
|
+
acts_as_commentable
|
22
|
+
end
|
23
|
+
|
24
|
+
ActiveRecord::Base.send(:include, Acts::CommentableWithThreading)
|
metadata
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_commentable_with_threading
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Evan Light
|
14
|
+
- Jack Dempsey
|
15
|
+
- Xelipe
|
16
|
+
- xxx
|
17
|
+
autorequire:
|
18
|
+
bindir: bin
|
19
|
+
cert_chain: []
|
20
|
+
|
21
|
+
date: 2011-12-02 00:00:00 -05:00
|
22
|
+
default_executable:
|
23
|
+
dependencies:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: rake
|
26
|
+
prerelease: false
|
27
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
hash: 3
|
33
|
+
segments:
|
34
|
+
- 0
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: bundler
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 15
|
47
|
+
segments:
|
48
|
+
- 1
|
49
|
+
- 0
|
50
|
+
version: "1.0"
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 9
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 3
|
65
|
+
version: "1.3"
|
66
|
+
type: :development
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: sqlite3-ruby
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id004
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rails
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 7
|
91
|
+
segments:
|
92
|
+
- 3
|
93
|
+
- 0
|
94
|
+
version: "3.0"
|
95
|
+
type: :development
|
96
|
+
version_requirements: *id005
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activerecord
|
99
|
+
prerelease: false
|
100
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ~>
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 7
|
106
|
+
segments:
|
107
|
+
- 3
|
108
|
+
- 0
|
109
|
+
version: "3.0"
|
110
|
+
type: :runtime
|
111
|
+
version_requirements: *id006
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: activesupport
|
114
|
+
prerelease: false
|
115
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
hash: 7
|
121
|
+
segments:
|
122
|
+
- 3
|
123
|
+
- 0
|
124
|
+
version: "3.0"
|
125
|
+
type: :runtime
|
126
|
+
version_requirements: *id007
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: moretea-awesome_nested_set
|
129
|
+
prerelease: false
|
130
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
type: :runtime
|
140
|
+
version_requirements: *id008
|
141
|
+
description: Polymorphic threaded comments Rails gem for Rails 3+
|
142
|
+
email: evan@tripledogdare.net
|
143
|
+
executables: []
|
144
|
+
|
145
|
+
extensions: []
|
146
|
+
|
147
|
+
extra_rdoc_files: []
|
148
|
+
|
149
|
+
files:
|
150
|
+
- .gitignore
|
151
|
+
- CHANGELOG
|
152
|
+
- Gemfile
|
153
|
+
- Gemfile.lock
|
154
|
+
- MIT-LICENSE
|
155
|
+
- README.md
|
156
|
+
- Rakefile
|
157
|
+
- acts_as_commentable_with_threading.gemspec
|
158
|
+
- init.rb
|
159
|
+
- install.rb
|
160
|
+
- lib/acts_as_commentable_with_threading.rb
|
161
|
+
- lib/generators/acts_as_commentable_upgrade_migration/USAGE
|
162
|
+
- lib/generators/acts_as_commentable_upgrade_migration/acts_as_commentable_upgrade_migration_generator.rb
|
163
|
+
- lib/generators/acts_as_commentable_upgrade_migration/comment.rb
|
164
|
+
- lib/generators/acts_as_commentable_upgrade_migration/templates/migration.rb
|
165
|
+
- lib/generators/acts_as_commentable_with_threading_migration/USAGE
|
166
|
+
- lib/generators/acts_as_commentable_with_threading_migration/acts_as_commentable_with_threading_migration_generator.rb
|
167
|
+
- lib/generators/acts_as_commentable_with_threading_migration/templates/comment.rb
|
168
|
+
- lib/generators/acts_as_commentable_with_threading_migration/templates/migration.rb
|
169
|
+
- rails/init.rb
|
170
|
+
- spec/comment_spec.rb
|
171
|
+
- spec/commentable_spec.rb
|
172
|
+
- spec/db/database.yml
|
173
|
+
- spec/db/schema.rb
|
174
|
+
- spec/spec_helper.rb
|
175
|
+
has_rdoc: true
|
176
|
+
homepage: http://github.com/elight/acts_as_commentable_with_threading
|
177
|
+
licenses: []
|
178
|
+
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
|
182
|
+
require_paths:
|
183
|
+
- lib
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
hash: 3
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
version: "0"
|
193
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
|
+
none: false
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
hash: 3
|
199
|
+
segments:
|
200
|
+
- 0
|
201
|
+
version: "0"
|
202
|
+
requirements: []
|
203
|
+
|
204
|
+
rubyforge_project:
|
205
|
+
rubygems_version: 1.3.7
|
206
|
+
signing_key:
|
207
|
+
specification_version: 3
|
208
|
+
summary: Polymorphic comments Rails gem - Rails 3+ only
|
209
|
+
test_files:
|
210
|
+
- spec/commentable_spec.rb
|
211
|
+
- spec/comment_spec.rb
|
212
|
+
- spec/spec_helper.rb
|
213
|
+
- spec/db/database.yml
|
214
|
+
- spec/db/schema.rb
|