commentable 0.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/.rspec +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +64 -0
- data/README.rdoc +82 -0
- data/Rakefile +5 -0
- data/commentable.gemspec +27 -0
- data/lib/commentable.rb +22 -0
- data/lib/commentable/class_methods.rb +8 -0
- data/lib/commentable/comment.rb +15 -0
- data/lib/commentable/instance_methods.rb +7 -0
- data/lib/commentable/user.rb +3 -0
- data/lib/commentable/version.rb +8 -0
- data/spec/commentable/comment_spec.rb +58 -0
- data/spec/commentable_spec.rb +20 -0
- data/spec/schema.rb +26 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/models.rb +10 -0
- metadata +151 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
commentable (0.1.0)
|
5
|
+
activerecord
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://gems.simplesideias.com.br/
|
9
|
+
specs:
|
10
|
+
activemodel (3.0.9)
|
11
|
+
activesupport (= 3.0.9)
|
12
|
+
builder (~> 2.1.2)
|
13
|
+
i18n (~> 0.5.0)
|
14
|
+
activerecord (3.0.9)
|
15
|
+
activemodel (= 3.0.9)
|
16
|
+
activesupport (= 3.0.9)
|
17
|
+
arel (~> 2.0.10)
|
18
|
+
tzinfo (~> 0.3.23)
|
19
|
+
activesupport (3.0.9)
|
20
|
+
archive-tar-minitar (0.5.2)
|
21
|
+
arel (2.0.10)
|
22
|
+
builder (2.1.2)
|
23
|
+
columnize (0.3.4)
|
24
|
+
diff-lcs (1.1.2)
|
25
|
+
i18n (0.5.0)
|
26
|
+
linecache19 (0.5.12)
|
27
|
+
ruby_core_source (>= 0.1.4)
|
28
|
+
notifier (0.1.3)
|
29
|
+
rake (0.8.7)
|
30
|
+
redcarpet (1.17.2)
|
31
|
+
rspec (2.6.0)
|
32
|
+
rspec-core (~> 2.6.0)
|
33
|
+
rspec-expectations (~> 2.6.0)
|
34
|
+
rspec-mocks (~> 2.6.0)
|
35
|
+
rspec-core (2.6.4)
|
36
|
+
rspec-expectations (2.6.0)
|
37
|
+
diff-lcs (~> 1.1.2)
|
38
|
+
rspec-mocks (2.6.0)
|
39
|
+
ruby-debug-base19 (0.11.25)
|
40
|
+
columnize (>= 0.3.1)
|
41
|
+
linecache19 (>= 0.5.11)
|
42
|
+
ruby_core_source (>= 0.1.4)
|
43
|
+
ruby-debug19 (0.11.6)
|
44
|
+
columnize (>= 0.3.1)
|
45
|
+
linecache19 (>= 0.5.11)
|
46
|
+
ruby-debug-base19 (>= 0.11.19)
|
47
|
+
ruby_core_source (0.1.5)
|
48
|
+
archive-tar-minitar (>= 0.5.2)
|
49
|
+
sqlite3 (1.3.4)
|
50
|
+
test_notifier (0.3.6)
|
51
|
+
notifier
|
52
|
+
tzinfo (0.3.29)
|
53
|
+
|
54
|
+
PLATFORMS
|
55
|
+
ruby
|
56
|
+
|
57
|
+
DEPENDENCIES
|
58
|
+
commentable!
|
59
|
+
rake (~> 0.8.7)
|
60
|
+
redcarpet (~> 1.17)
|
61
|
+
rspec (~> 2.6)
|
62
|
+
ruby-debug19
|
63
|
+
sqlite3 (~> 1.3)
|
64
|
+
test_notifier (~> 0.3.6)
|
data/README.rdoc
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
= Commentable
|
2
|
+
|
3
|
+
This is a really simple ActiveRecord plugin that allows models to be commented.
|
4
|
+
|
5
|
+
Commentable is tightly coupled to an User model. If you don't have it, there's no game for you here.
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
gem install commentable
|
10
|
+
|
11
|
+
== Usage
|
12
|
+
|
13
|
+
First, you'll have to create the comments table. Run `rails generate migration create_comments` and add the following code:
|
14
|
+
|
15
|
+
class CreateComments < ActiveRecord::Migration
|
16
|
+
def self.up
|
17
|
+
create_table :comments do |t|
|
18
|
+
t.text :body, :formatted_body
|
19
|
+
t.references :commentable, :polymorphic => true
|
20
|
+
t.references :user
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
|
24
|
+
add_index :comments, [:commentable_id, :commentable_type], :name => "index_on_commentable"
|
25
|
+
add_index :comments, [:commentable_id, :commentable_type, :user_id], :name => "index_on_commentable_and_user"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.down
|
29
|
+
drop_table :comments
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Run `rake db:migrate` to apply this new migration.
|
34
|
+
|
35
|
+
Now, add the `commentable` macro to all models that can be commented.
|
36
|
+
|
37
|
+
class Task < ActiveRecord::Base
|
38
|
+
commentable
|
39
|
+
end
|
40
|
+
|
41
|
+
This will create an association called `comments`. You can now create comments like any ActiveRecord model.
|
42
|
+
|
43
|
+
comment = @task.comments.create(:body => "Awesome job!", :user => @user)
|
44
|
+
|
45
|
+
There's a shortcut for that.
|
46
|
+
|
47
|
+
comment = @task.add_comment(:body => "Awesome job!", :user => @user)
|
48
|
+
|
49
|
+
You can have formatted comments. This is specially useful if you want to provide Markdown support, for instance. Just use the `:format` option passing any variable that responds to the `call` method. The block's return will be used as the `formatted_body` attribute.
|
50
|
+
|
51
|
+
class Task < ActiveRecord::Base
|
52
|
+
commentable :format => proc {|comment| Redcarpet.new(comment.body.to_s).to_html}
|
53
|
+
end
|
54
|
+
|
55
|
+
<b>Final note:</b> remember to add a `comments_count` column to every single model that will be commentable. This is required by the Comment model.
|
56
|
+
|
57
|
+
== Maintainer
|
58
|
+
|
59
|
+
* Nando Vieira (http://nandovieira.com.br)
|
60
|
+
|
61
|
+
== License
|
62
|
+
|
63
|
+
(The MIT License)
|
64
|
+
|
65
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
66
|
+
a copy of this software and associated documentation files (the
|
67
|
+
'Software'), to deal in the Software without restriction, including
|
68
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
69
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
70
|
+
permit persons to whom the Software is furnished to do so, subject to
|
71
|
+
the following conditions:
|
72
|
+
|
73
|
+
The above copyright notice and this permission notice shall be
|
74
|
+
included in all copies or substantial portions of the Software.
|
75
|
+
|
76
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
77
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
78
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
79
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
80
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
81
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
82
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/commentable.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "commentable/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "commentable"
|
7
|
+
s.version = Commentable::Version::STRING
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Nando Vieira"]
|
10
|
+
s.email = ["fnando.vieira@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/commentable"
|
12
|
+
s.summary = "Add comment support for ActiveRecord models."
|
13
|
+
s.description = s.summary
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency "activerecord"
|
21
|
+
s.add_development_dependency "rake", "~> 0.8.7"
|
22
|
+
s.add_development_dependency "rspec", "~> 2.6"
|
23
|
+
s.add_development_dependency "sqlite3", "~> 1.3"
|
24
|
+
s.add_development_dependency "test_notifier", "~> 0.3.6"
|
25
|
+
s.add_development_dependency "ruby-debug19"
|
26
|
+
s.add_development_dependency "redcarpet", "~> 1.17"
|
27
|
+
end
|
data/lib/commentable.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "active_record"
|
2
|
+
require "commentable/comment"
|
3
|
+
require "commentable/user"
|
4
|
+
|
5
|
+
module Commentable
|
6
|
+
autoload :Version, "commentable/version"
|
7
|
+
autoload :InstanceMethods, "commentable/instance_methods"
|
8
|
+
autoload :ClassMethods, "commentable/class_methods"
|
9
|
+
|
10
|
+
def self.extended(base)
|
11
|
+
base.class_eval do
|
12
|
+
include InstanceMethods
|
13
|
+
extend ClassMethods
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :commentable_options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Base.extend(Commentable)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Comment < ActiveRecord::Base
|
2
|
+
belongs_to :commentable, :polymorphic => true, :counter_cache => true
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
validates_presence_of :body
|
6
|
+
validates_presence_of :user, :commentable
|
7
|
+
|
8
|
+
before_save :generate_formatted_body
|
9
|
+
|
10
|
+
private
|
11
|
+
def generate_formatted_body
|
12
|
+
formatter = commentable.class.commentable_options[:format]
|
13
|
+
write_attribute :formatted_body, formatter.call(self) if formatter.respond_to?(:call)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Comment do
|
4
|
+
let(:user) { User.create }
|
5
|
+
let(:project) { Project.create }
|
6
|
+
let(:task) { Task.create }
|
7
|
+
subject { project.add_comment(:body => "Some comment", :user => user) }
|
8
|
+
|
9
|
+
context "validations" do
|
10
|
+
it "requires body" do
|
11
|
+
subject.body = nil
|
12
|
+
subject.valid?
|
13
|
+
subject.errors[:body].should_not be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "requires user" do
|
17
|
+
subject.user = nil
|
18
|
+
subject.valid?
|
19
|
+
subject.errors[:user].should_not be_empty
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "associations" do
|
24
|
+
its(:user) { should be_an(User) }
|
25
|
+
its(:commentable) { should be_a(Project) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "counter" do
|
29
|
+
it "increments counter" do
|
30
|
+
expect {
|
31
|
+
project.add_comment(:body => "Some comment", :user => user)
|
32
|
+
}.to change { project.reload.comments_count }.by(1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "formatting" do
|
37
|
+
it "saves formatted body" do
|
38
|
+
subject = task.comments.create(:body => "# Commentable", :user => user)
|
39
|
+
subject.formatted_body.should include("<h1>Commentable</h1>")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "removing" do
|
44
|
+
let(:user) { User.create }
|
45
|
+
let(:task) { Task.create }
|
46
|
+
let(:comment) { task.add_comment(:body => "Some comment", :user => user) }
|
47
|
+
|
48
|
+
it "nullifies existing records when user is removed" do
|
49
|
+
user.destroy
|
50
|
+
comment.reload.user.should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "removes existing records when commentable is removed" do
|
54
|
+
task.destroy
|
55
|
+
Comment.where(:commentable_id => task.id, :commentable_type => task.class.name).count.should be_zero
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Commentable do
|
4
|
+
let(:user) { User.create }
|
5
|
+
let(:project) { Project.create }
|
6
|
+
|
7
|
+
it "injects association" do
|
8
|
+
Project.new.should respond_to(:comments)
|
9
|
+
Task.new.should respond_to(:comments)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "skips association" do
|
13
|
+
List.new.should_not respond_to(:comments)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "adds new comment shortcut" do
|
17
|
+
project.comments.should_receive(:create).with(:body => "Some comment", :user => user)
|
18
|
+
project.add_comment(:body => "Some comment", :user => user)
|
19
|
+
end
|
20
|
+
end
|
data/spec/schema.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
ActiveRecord::Schema.define(:version => 0) do
|
2
|
+
create_table :comments do |t|
|
3
|
+
t.text :body, :formatted_body
|
4
|
+
t.references :commentable, :polymorphic => true
|
5
|
+
t.references :user
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :comments, [:commentable_id, :commentable_type], :name => "index_on_commentable"
|
10
|
+
add_index :comments, [:commentable_id, :commentable_type, :user_id], :name => "index_on_commentable_and_user"
|
11
|
+
|
12
|
+
create_table :projects do |t|
|
13
|
+
t.integer :comments_count, :null => false, :default => 0
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :tasks do |t|
|
17
|
+
t.integer :comments_count, :null => false, :default => 0
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table :lists do |t|
|
21
|
+
t.integer :comments_count, :null => false, :default => 0
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :users do |t|
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup(:default, :development)
|
3
|
+
Bundler.require
|
4
|
+
|
5
|
+
require "commentable"
|
6
|
+
require "test_notifier/runner/rspec"
|
7
|
+
require "redcarpet"
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
10
|
+
load File.dirname(__FILE__) + "/schema.rb"
|
11
|
+
|
12
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each do |file|
|
13
|
+
require file
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: commentable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nando Vieira
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-01 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: &2156389380 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2156389380
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &2156388840 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.7
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2156388840
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &2156388300 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.6'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2156388300
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sqlite3
|
49
|
+
requirement: &2156387820 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2156387820
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: test_notifier
|
60
|
+
requirement: &2156387340 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.3.6
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2156387340
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ruby-debug19
|
71
|
+
requirement: &2156386960 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2156386960
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: redcarpet
|
82
|
+
requirement: &2156264260 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.17'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2156264260
|
91
|
+
description: Add comment support for ActiveRecord models.
|
92
|
+
email:
|
93
|
+
- fnando.vieira@gmail.com
|
94
|
+
executables: []
|
95
|
+
extensions: []
|
96
|
+
extra_rdoc_files: []
|
97
|
+
files:
|
98
|
+
- .gitignore
|
99
|
+
- .rspec
|
100
|
+
- Gemfile
|
101
|
+
- Gemfile.lock
|
102
|
+
- README.rdoc
|
103
|
+
- Rakefile
|
104
|
+
- commentable.gemspec
|
105
|
+
- lib/commentable.rb
|
106
|
+
- lib/commentable/class_methods.rb
|
107
|
+
- lib/commentable/comment.rb
|
108
|
+
- lib/commentable/instance_methods.rb
|
109
|
+
- lib/commentable/user.rb
|
110
|
+
- lib/commentable/version.rb
|
111
|
+
- spec/commentable/comment_spec.rb
|
112
|
+
- spec/commentable_spec.rb
|
113
|
+
- spec/schema.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
- spec/support/models.rb
|
116
|
+
homepage: http://rubygems.org/gems/commentable
|
117
|
+
licenses: []
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
segments:
|
129
|
+
- 0
|
130
|
+
hash: -1833029340048367188
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: -1833029340048367188
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.8.5
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Add comment support for ActiveRecord models.
|
146
|
+
test_files:
|
147
|
+
- spec/commentable/comment_spec.rb
|
148
|
+
- spec/commentable_spec.rb
|
149
|
+
- spec/schema.rb
|
150
|
+
- spec/spec_helper.rb
|
151
|
+
- spec/support/models.rb
|