commontator 1.1.3 → 2.0.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.
Files changed (42) hide show
  1. data/app/controllers/commontator/comments_controller.rb +3 -2
  2. data/app/controllers/commontator/comments_controller.rb~ +136 -0
  3. data/app/models/commontator/comment.rb +53 -36
  4. data/app/models/commontator/comment.rb~ +108 -0
  5. data/app/models/commontator/subscription.rb +8 -6
  6. data/app/models/commontator/subscription.rb~ +21 -0
  7. data/app/models/commontator/thread.rb +48 -44
  8. data/app/models/commontator/thread.rb~ +48 -47
  9. data/app/views/commontator/comments/_body.html.erb +1 -1
  10. data/app/views/commontator/comments/_body.html.erb~ +8 -0
  11. data/app/views/commontator/comments/_form.html.erb +1 -1
  12. data/app/views/commontator/comments/_form.html.erb~ +38 -0
  13. data/app/views/commontator/comments/_show.html.erb +1 -1
  14. data/app/views/commontator/comments/_show.html.erb~ +44 -0
  15. data/app/views/commontator/comments/_votes.html.erb +1 -1
  16. data/app/views/commontator/comments/_votes.html.erb~ +57 -0
  17. data/app/views/commontator/comments/delete.js.erb +1 -1
  18. data/app/views/commontator/comments/delete.js.erb~ +17 -0
  19. data/config/initializers/commontator.rb +11 -4
  20. data/config/initializers/commontator.rb~ +171 -0
  21. data/db/migrate/0_install.rb +23 -21
  22. data/db/migrate/0_install.rb~ +23 -21
  23. data/lib/commontator.rb +2 -0
  24. data/lib/commontator.rb~ +1 -1
  25. data/lib/commontator/acts_as_commontable.rb +7 -6
  26. data/lib/commontator/acts_as_commontable.rb~ +8 -6
  27. data/lib/commontator/acts_as_commontator.rb +4 -3
  28. data/lib/commontator/acts_as_commontator.rb~ +31 -0
  29. data/lib/commontator/version.rb +1 -1
  30. data/lib/commontator/version.rb~ +1 -1
  31. data/spec/app/controllers/commontator/comments_controller_spec.rb +61 -20
  32. data/spec/app/controllers/commontator/comments_controller_spec.rb~ +58 -21
  33. data/spec/app/models/commontator/comment_spec.rb +8 -7
  34. data/spec/app/models/commontator/comment_spec.rb~ +9 -8
  35. data/spec/app/models/commontator/thread_spec.rb +1 -1
  36. data/spec/app/models/commontator/thread_spec.rb~ +1 -1
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/schema.rb +16 -16
  39. data/spec/dummy/db/test.sqlite3 +0 -0
  40. data/spec/dummy/log/development.log +724 -0
  41. data/spec/dummy/log/test.log +41005 -0
  42. metadata +12 -2
@@ -51,6 +51,7 @@ module Commontator
51
51
  # PUT /comments/1
52
52
  def update
53
53
  raise SecurityTransgression unless @comment.can_be_edited_by?(@user)
54
+ @comment.editor = @user
54
55
 
55
56
  respond_to do |format|
56
57
  if @comment.update_attributes(params[:comment])
@@ -68,7 +69,7 @@ module Commontator
68
69
  raise SecurityTransgression unless @comment.can_be_deleted_by?(@user)
69
70
 
70
71
  @comment.errors.add(:base, 'This comment has already been deleted.') \
71
- unless @comment.delete(@user)
72
+ unless @comment.delete_by(@user)
72
73
 
73
74
  respond_to do |format|
74
75
  format.html { redirect_to @thread }
@@ -81,7 +82,7 @@ module Commontator
81
82
  raise SecurityTransgression unless @comment.can_be_deleted_by?(@user)
82
83
 
83
84
  @comment.errors.add(:base, 'This comment is not deleted.') \
84
- unless @comment.undelete
85
+ unless @comment.undelete_by(@user)
85
86
 
86
87
  respond_to do |format|
87
88
  format.html { redirect_to @thread }
@@ -0,0 +1,136 @@
1
+ module Commontator
2
+ class CommentsController < ApplicationController
3
+ before_filter :get_thread, :only => [:new, :create]
4
+ before_filter :get_comment_and_thread, :except => [:new, :create]
5
+ before_filter :set_commontable_url, :only => :create
6
+
7
+ # GET /1/comments/new
8
+ def new
9
+ @comment = Comment.new
10
+ @comment.thread = @thread
11
+ @comment.creator = @user
12
+
13
+ raise SecurityTransgression unless @comment.can_be_created_by?(@user)
14
+
15
+ respond_to do |format|
16
+ format.html { redirect_to @thread }
17
+ format.js
18
+ end
19
+
20
+ end
21
+
22
+ # POST /1/comments
23
+ def create
24
+ @comment = Comment.new(params[:comment])
25
+ @comment.thread = @thread
26
+ @comment.creator = @user
27
+
28
+ raise SecurityTransgression unless @comment.can_be_created_by?(@user)
29
+
30
+ respond_to do |format|
31
+ if @comment.save
32
+ format.html { redirect_to @thread }
33
+ format.js
34
+ else
35
+ format.html { redirect_to @thread }
36
+ format.js { render :new }
37
+ end
38
+ end
39
+ end
40
+
41
+ # GET /comments/1/edit
42
+ def edit
43
+ raise SecurityTransgression unless @comment.can_be_edited_by?(@user)
44
+
45
+ respond_to do |format|
46
+ format.html { redirect_to @thread }
47
+ format.js
48
+ end
49
+ end
50
+
51
+ # PUT /comments/1
52
+ def update
53
+ raise SecurityTransgression unless @comment.can_be_edited_by?(@user)
54
+ @comment.editor = @user
55
+
56
+ respond_to do |format|
57
+ if @comment.update_attributes(params[:comment])
58
+ format.html { redirect_to @thread }
59
+ format.js
60
+ else
61
+ format.html { redirect_to @thread }
62
+ format.js { render :edit }
63
+ end
64
+ end
65
+ end
66
+
67
+ # PUT /comments/1/delete
68
+ def delete
69
+ raise SecurityTransgression unless @comment.can_be_deleted_by?(@user)
70
+
71
+ @comment.errors.add(:base, 'This comment has already been deleted.') \
72
+ unless @comment.delete(@user)
73
+
74
+ respond_to do |format|
75
+ format.html { redirect_to @thread }
76
+ format.js { render :delete }
77
+ end
78
+ end
79
+
80
+ # PUT /comments/1/undelete
81
+ def undelete
82
+ raise SecurityTransgression unless @comment.can_be_deleted_by?(@user)
83
+
84
+ @comment.errors.add(:base, 'This comment is not deleted.') \
85
+ unless @comment.undelete_by(@user)
86
+
87
+ respond_to do |format|
88
+ format.html { redirect_to @thread }
89
+ format.js { render :delete }
90
+ end
91
+ end
92
+
93
+ # PUT /comments/1/upvote
94
+ def upvote
95
+ raise SecurityTransgression unless @comment.can_be_voted_on_by?(@user)
96
+
97
+ @comment.upvote_from @user
98
+
99
+ respond_to do |format|
100
+ format.html { redirect_to @thread }
101
+ format.js { render :vote }
102
+ end
103
+ end
104
+
105
+ # PUT /comments/1/downvote
106
+ def downvote
107
+ raise SecurityTransgression unless @comment.can_be_voted_on_by?(@user)
108
+
109
+ @comment.downvote_from @user
110
+
111
+ respond_to do |format|
112
+ format.html { redirect_to @thread }
113
+ format.js { render :vote }
114
+ end
115
+ end
116
+
117
+ # PUT /comments/1/unvote
118
+ def unvote
119
+ raise SecurityTransgression unless @comment.can_be_voted_on_by?(@user)
120
+
121
+ @comment.unvote :voter => @user
122
+
123
+ respond_to do |format|
124
+ format.html { redirect_to @thread }
125
+ format.js { render :vote }
126
+ end
127
+ end
128
+
129
+ protected
130
+
131
+ def get_comment_and_thread
132
+ @comment = Comment.find(params[:id])
133
+ @thread = @comment.thread
134
+ end
135
+ end
136
+ end
@@ -1,60 +1,78 @@
1
1
  module Commontator
2
2
  class Comment < ActiveRecord::Base
3
3
  belongs_to :creator, :polymorphic => true
4
- belongs_to :deleter, :polymorphic => true
4
+ belongs_to :editor, :polymorphic => true
5
+
5
6
  belongs_to :thread
6
-
7
+
7
8
  has_one :commontable, :through => :thread
8
-
9
+
10
+ attr_accessible :body
11
+
9
12
  validates_presence_of :creator, :on => :create
13
+ validates_presence_of :editor, :on => :update
14
+
10
15
  validates_presence_of :thread
11
16
  validates_presence_of :body
12
17
 
13
- attr_accessible :body
14
-
18
+ validates_uniqueness_of :body, :scope => [:creator_type, :creator_id, :thread_id],
19
+ :message => 'has already been posted'
20
+
21
+ protected
22
+
15
23
  cattr_accessor :acts_as_votable_initialized
16
-
24
+
25
+ public
26
+
17
27
  def is_votable?
28
+ return true if acts_as_votable_initialized
18
29
  return false unless self.class.respond_to?(:acts_as_votable)
19
- self.class.acts_as_votable unless acts_as_votable_initialized
30
+ self.class.acts_as_votable
20
31
  self.class.acts_as_votable_initialized = true
21
32
  end
22
-
33
+
34
+ def get_vote_by(user)
35
+ return nil unless is_votable?
36
+ votes.where(:voter_type => user.class.name, :voter_id => user.id).first
37
+ end
38
+
23
39
  def is_modified?
24
- updated_at != created_at
40
+ !editor.nil?
25
41
  end
26
-
42
+
27
43
  def is_deleted?
28
44
  !deleted_at.blank?
29
45
  end
30
-
31
- def timestamp
32
- config = thread.config
33
- (is_modified? ? 'Last modified on ' : \
34
- "#{config.comment_create_verb_past.capitalize} on ") + \
35
- updated_at.strftime(config.timestamp_format)
36
- end
37
-
38
- def delete(user = nil)
46
+
47
+ def delete_by(user)
39
48
  return false if is_deleted?
40
49
  self.deleted_at = Time.now
41
- self.deleter = user
42
- self.save!
50
+ self.editor = user
51
+ self.save
43
52
  end
44
-
45
- def undelete
53
+
54
+ def undelete_by(user)
46
55
  return false unless is_deleted?
47
56
  self.deleted_at = nil
48
- self.save!
57
+ self.editor = user
58
+ self.save
49
59
  end
50
60
 
51
- ##########################
52
- # Access control methods #
53
- ##########################
54
-
61
+ def timestamp
62
+ config = thread.config
63
+ "#{config.comment_create_verb_past.capitalize} on " + \
64
+ created_at.strftime(config.timestamp_format) + \
65
+ (is_modified? ? " | Last #{config.comment_edit_verb_past} on " + \
66
+ updated_at.strftime(config.timestamp_format) : '')
67
+ end
68
+
69
+ ##################
70
+ # Access Control #
71
+ ##################
72
+
55
73
  def can_be_read_by?(user)
56
- (thread.can_be_read_by?(user) && (!is_deleted? ||\
57
- thread.config.deleted_comments_are_visible)) ||\
74
+ (thread.can_be_read_by?(user) && \
75
+ (!is_deleted? || thread.config.deleted_comments_are_visible)) ||\
58
76
  thread.can_be_edited_by?(user)
59
77
  end
60
78
 
@@ -72,20 +90,19 @@ module Commontator
72
90
  def can_be_deleted_by?(user)
73
91
  (!thread.is_closed? &&\
74
92
  ((user == creator && thread.config.can_delete_own_comments && \
75
- thread.can_be_read_by?(user) && (!is_deleted? || deleter == user)) &&\
93
+ thread.can_be_read_by?(user) && (!is_deleted? || editor == user)) &&\
76
94
  (thread.comments.last == self || thread.config.can_delete_old_comments))) ||\
77
95
  thread.can_be_edited_by?(user)
78
96
  end
79
-
97
+
80
98
  def can_be_voted_on?
81
- is_votable? && !is_deleted? && thread.config.can_vote_on_comments
99
+ !thread.is_closed? && is_votable? && !is_deleted? && thread.config.can_vote_on_comments
82
100
  end
83
101
 
84
102
  def can_be_voted_on_by?(user)
85
- can_be_voted_on? && !thread.is_closed? &&\
86
- thread.can_be_read_by?(user) && user != creator
103
+ can_be_voted_on? && thread.can_be_read_by?(user) && user != creator
87
104
  end
88
105
  end
89
-
106
+
90
107
  CommentObserver.instance
91
108
  end
@@ -0,0 +1,108 @@
1
+ module Commontator
2
+ class Comment < ActiveRecord::Base
3
+ belongs_to :creator, :polymorphic => true
4
+ belongs_to :editor, :polymorphic => true
5
+
6
+ belongs_to :thread
7
+
8
+ has_one :commontable, :through => :thread
9
+
10
+ attr_accessible :body
11
+
12
+ validates_presence_of :creator, :on => :create
13
+ validates_presence_of :editor, :on => :update
14
+
15
+ validates_presence_of :thread
16
+ validates_presence_of :body
17
+
18
+ validates_uniqueness_of :body, :scope => [:creator_type, :creator_id, :thread_id],
19
+ :message => 'has already been posted'
20
+
21
+ protected
22
+
23
+ cattr_accessor :acts_as_votable_initialized
24
+
25
+ public
26
+
27
+ def is_votable?
28
+ return true if acts_as_votable_initialized
29
+ return false unless self.class.respond_to?(:acts_as_votable)
30
+ self.class.acts_as_votable
31
+ self.class.acts_as_votable_initialized = true
32
+ end
33
+
34
+ def get_vote_by(user)
35
+ return nil unless is_votable?
36
+ votes.where(:voter_type => user.class.name, :voter_id => user.id).first
37
+ end
38
+
39
+ def is_modified?
40
+ !editor.nil?
41
+ end
42
+
43
+ def is_deleted?
44
+ !deleted_at.blank?
45
+ end
46
+
47
+ def delete_by(user)
48
+ return false if is_deleted?
49
+ self.deleted_at = Time.now
50
+ self.editor = user
51
+ self.save
52
+ end
53
+
54
+ def undelete_by(user)
55
+ return false unless is_deleted?
56
+ self.deleted_at = nil
57
+ self.editor = user
58
+ self.save
59
+ end
60
+
61
+ def timestamp
62
+ config = thread.config
63
+ "#{config.comment_create_verb_past.capitalize} on ") + \
64
+ created_at.strftime(config.timestamp_format) + \
65
+ (is_modified? ? " | Last #{config.comment_edit_verb_past} on " + \
66
+ updated_at.strftime(config.timestamp_format) : '')
67
+ end
68
+
69
+ ##################
70
+ # Access Control #
71
+ ##################
72
+
73
+ def can_be_read_by?(user)
74
+ (thread.can_be_read_by?(user) && \
75
+ (!is_deleted? || thread.config.deleted_comments_are_visible)) ||\
76
+ thread.can_be_edited_by?(user)
77
+ end
78
+
79
+ def can_be_created_by?(user)
80
+ !thread.is_closed? && thread.can_be_read_by?(user) && user == creator
81
+ end
82
+
83
+ def can_be_edited_by?(user)
84
+ !thread.is_closed? && !is_deleted? &&\
85
+ ((user == creator && thread.config.can_edit_own_comments && thread.can_be_read_by?(user)) ||\
86
+ (thread.can_be_edited_by?(user) && thread.config.admin_can_edit_comments)) &&\
87
+ (thread.comments.last == self || thread.config.can_edit_old_comments)
88
+ end
89
+
90
+ def can_be_deleted_by?(user)
91
+ (!thread.is_closed? &&\
92
+ ((user == creator && thread.config.can_delete_own_comments && \
93
+ thread.can_be_read_by?(user) && (!is_deleted? || editor == user)) &&\
94
+ (thread.comments.last == self || thread.config.can_delete_old_comments))) ||\
95
+ thread.can_be_edited_by?(user)
96
+ end
97
+
98
+ def can_be_voted_on?
99
+ !thread.is_closed? && is_votable? && !is_deleted? && thread.config.can_vote_on_comments
100
+ end
101
+
102
+ def can_be_voted_on_by?(user)
103
+ can_be_voted_on? && thread.can_be_read_by?(user) && user != creator
104
+ end
105
+ end
106
+
107
+ CommentObserver.instance
108
+ end
@@ -1,19 +1,21 @@
1
1
  module Commontator
2
2
  class Subscription < ActiveRecord::Base
3
3
  belongs_to :subscriber, :polymorphic => true
4
+
4
5
  belongs_to :thread
5
6
 
6
- validates_presence_of :subscriber, :thread
7
- validates_uniqueness_of :thread_id, :scope => [:subscriber_id, :subscriber_type]
8
-
9
7
  attr_accessible :subscriber, :thread
10
-
8
+
9
+ validates_presence_of :subscriber, :thread
10
+
11
+ validates_uniqueness_of :thread_id, :scope => [:subscriber_type, :subscriber_id]
12
+
11
13
  def mark_as_read
12
- self.update_attribute(:unread, 0)
14
+ update_attribute(:unread, 0)
13
15
  end
14
16
 
15
17
  def add_unread
16
- self.update_attribute(:unread, unread + 1)
18
+ update_attribute(:unread, unread + 1)
17
19
  end
18
20
  end
19
21
  end
@@ -0,0 +1,21 @@
1
+ module Commontator
2
+ class Subscription < ActiveRecord::Base
3
+ belongs_to :subscriber, :polymorphic => true
4
+
5
+ belongs_to :thread
6
+
7
+ attr_accessible :subscriber, :thread
8
+
9
+ validates_presence_of :subscriber, :thread
10
+
11
+ validates_uniqueness_of :thread_id, :scope => [:subscriber_type, :subscriber_id]
12
+
13
+ def mark_as_read
14
+ self.update_attribute(:unread, 0)
15
+ end
16
+
17
+ def add_unread
18
+ self.update_attribute(:unread, unread + 1)
19
+ end
20
+ end
21
+ end