muck-comments 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/MIT-LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +76 -0
- data/VERSION +1 -0
- data/app/controllers/muck/comments_controller.rb +75 -0
- data/app/helpers/muck_comments_helper.rb +17 -0
- data/app/views/activity_templates/_comment.html.erb +8 -0
- data/app/views/comments/_comment.html.erb +26 -0
- data/app/views/comments/_comment_title.html.erb +14 -0
- data/app/views/comments/_form.html.erb +7 -0
- data/config/muck_comments_routes.rb +3 -0
- data/db/migrate/20090613173314_create_comments.rb +24 -0
- data/install.rb +1 -0
- data/lib/active_record/acts/muck_comment.rb +78 -0
- data/lib/acts_as_commentable_with_threading.rb +75 -0
- data/lib/muck_comments/initialize_routes.rb +8 -0
- data/lib/muck_comments/tasks.rb +28 -0
- data/lib/muck_comments.rb +5 -0
- data/locales/en.yml +8 -0
- data/muck-comments.gemspec +97 -0
- data/pkg/muck-comments-0.1.0.gem +0 -0
- data/rails/init.rb +4 -0
- data/tasks/muck_comments_tasks.rake +1 -0
- data/test/db/database.yml +18 -0
- data/test/db/schema.rb +25 -0
- data/test/factories.rb +8 -0
- data/test/functional/comments_controller_test.rb +34 -0
- data/test/test_helper.rb +44 -0
- data/test/unit/comment_test.rb +49 -0
- data/test/unit/commentable_test.rb +7 -0
- data/uninstall.rb +1 -0
- metadata +107 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 [name of plugin creator]
|
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.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
= MuckComments
|
2
|
+
|
3
|
+
Add comments to any object. This gem is the muck version of acts_as_commentable_with_threading (http://github.com/elight/acts_as_commentable_with_threading/tree/master)
|
4
|
+
|
5
|
+
== Setup
|
6
|
+
Install the the awesome_nested_set gem (http://github.com/collectiveidea/awesome_nested_set/tree/master)
|
7
|
+
|
8
|
+
gem sources -a http://gems.github.com
|
9
|
+
sudo gem install collectiveidea-awesome_nested_set
|
10
|
+
|
11
|
+
Then add it to your environment.rb:
|
12
|
+
|
13
|
+
config.gem "collectiveidea-awesome_nested_set", :lib => 'awesome_nested_set'
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
=== Comment model
|
18
|
+
Create a model called comment in your project and add the following:
|
19
|
+
|
20
|
+
class Comment < ActiveRecord::Base
|
21
|
+
acts_as_muck_comment
|
22
|
+
end
|
23
|
+
This let's you add any other methods to the comment model that you see fit.
|
24
|
+
|
25
|
+
=== Comment controller
|
26
|
+
Override the comments controller to change the the security model. For example:
|
27
|
+
|
28
|
+
class Muck::CommentsController < ApplicationController
|
29
|
+
|
30
|
+
before_filter :login_required # require the user to be logged in to make a comment
|
31
|
+
|
32
|
+
# Modify this method to change how permissions are checked to see if a user can comment.
|
33
|
+
# Each model that implements 'acts_as_muck_comment' can override can_comment? to
|
34
|
+
# change how comment permissions are handled.
|
35
|
+
def has_permission_to_comment(user, parent)
|
36
|
+
parent.can_comment?(user)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
Copyright (c) 2009 Justin Ball, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the muck_comments plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the muck_comments plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'MuckComments'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'jeweler'
|
27
|
+
Jeweler::Tasks.new do |gemspec|
|
28
|
+
gemspec.name = "muck-comments"
|
29
|
+
gemspec.summary = "The comment engine for the muck system"
|
30
|
+
gemspec.email = "justinball@gmail.com"
|
31
|
+
gemspec.homepage = "http://github.com/jbasdf/muck_comments"
|
32
|
+
gemspec.description = "The comment engine for the muck system."
|
33
|
+
gemspec.authors = ["Justin Ball"]
|
34
|
+
gemspec.rubyforge_project = 'muck-comments'
|
35
|
+
gemspec.add_dependency "muck-engine"
|
36
|
+
gemspec.add_dependency "muck-users"
|
37
|
+
gemspec.files.include %w( tasks/*
|
38
|
+
db/migrate/*.rb
|
39
|
+
app/**/**/**/*
|
40
|
+
config/*
|
41
|
+
locales/*
|
42
|
+
rails/*
|
43
|
+
test/*
|
44
|
+
lib/**/*
|
45
|
+
public/javascripts/* )
|
46
|
+
end
|
47
|
+
rescue LoadError
|
48
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
49
|
+
end
|
50
|
+
|
51
|
+
# rubyforge tasks
|
52
|
+
begin
|
53
|
+
require 'rake/contrib/sshpublisher'
|
54
|
+
namespace :rubyforge do
|
55
|
+
|
56
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
57
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
58
|
+
|
59
|
+
namespace :release do
|
60
|
+
desc "Publish RDoc to RubyForge."
|
61
|
+
task :docs => [:rdoc] do
|
62
|
+
config = YAML.load(
|
63
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
64
|
+
)
|
65
|
+
|
66
|
+
host = "#{config['username']}@rubyforge.org"
|
67
|
+
remote_dir = "/var/www/gforge-projects/muck-comments/"
|
68
|
+
local_dir = 'rdoc'
|
69
|
+
|
70
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
rescue LoadError
|
75
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
76
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Muck::CommentsController < ApplicationController
|
2
|
+
unloadable
|
3
|
+
|
4
|
+
before_filter :get_parent, :only => [:create]
|
5
|
+
before_filter :get_comment, :only => [:destroy]
|
6
|
+
|
7
|
+
def create
|
8
|
+
@comment = @parent.comments.build(params[:comment])
|
9
|
+
@comment.user = current_user
|
10
|
+
@comment.save!
|
11
|
+
respond_to do |format|
|
12
|
+
format.html do
|
13
|
+
redirect_back_or_default(@parent)
|
14
|
+
end
|
15
|
+
format.json { render :json => { :success => true, :comment => @comment } }
|
16
|
+
end
|
17
|
+
rescue ActiveRecord::RecordInvalid => ex
|
18
|
+
if @comment
|
19
|
+
@errors = @comment.errors.full_messages.to_sentence
|
20
|
+
else
|
21
|
+
@errors = ex
|
22
|
+
end
|
23
|
+
message = t('muck.comments.create_error', :errors => @errors)
|
24
|
+
respond_to do |format|
|
25
|
+
format.html do
|
26
|
+
flash[:error] = message
|
27
|
+
redirect_back_or_default(@parent)
|
28
|
+
end
|
29
|
+
format.json { render :json => { :success => false, :message => message, :errors => @errors } }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
@comment.destroy
|
35
|
+
respond_to do |format|
|
36
|
+
format.html do
|
37
|
+
flash[:notice] = t('muck.comments.comment_removed')
|
38
|
+
redirect_back_or_default(current_user)
|
39
|
+
end
|
40
|
+
format.json { render :json => { :success => true, :message => t("muck.comments.comment_removed"), :comment_id => @comment.id } }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def get_parent
|
47
|
+
if !params[:parent_type] || !params[:parent_id]
|
48
|
+
raise t('muck.comments.missing_parent_id_error')
|
49
|
+
return
|
50
|
+
end
|
51
|
+
@klass = params[:parent_type].to_s.capitalize.constantize
|
52
|
+
@parent = @klass.find(params[:parent_id])
|
53
|
+
unless has_permission_to_comment(current_user, @parent)
|
54
|
+
permission_denied
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_comment
|
59
|
+
@comment = Comment.find(params[:id])
|
60
|
+
unless @comment.can_edit?(current_user)
|
61
|
+
respond_to do |format|
|
62
|
+
format.html do
|
63
|
+
flash[:notice] = I18n.t('muck.comments.cant_delete_comment')
|
64
|
+
redirect_back_or_default current_user
|
65
|
+
end
|
66
|
+
format.js { render(:update){|page| page.alert I18n.t('muck.comments.cant_delete_comment')}}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_permission_to_comment(user, parent)
|
72
|
+
parent.can_comment?(user)
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MuckCommentsHelper
|
2
|
+
|
3
|
+
# parent is the object to which the comments will be attached
|
4
|
+
# comment is the optional parent comment for the new comment.
|
5
|
+
def comment_form(parent, comment = nil)
|
6
|
+
render :partial => 'comments/form', :locals => {:parent => parent, :comment => comment}
|
7
|
+
end
|
8
|
+
|
9
|
+
def new_comment_path_with_parent(parent)
|
10
|
+
comments_path(make_parent_params(parent))
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_parent_params(parent)
|
14
|
+
{ :parent_id => parent.id, :parent_type => parent.class.to_s }
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div class="activity activity-status-update delete-container" id="<%= activity.dom_id %>">
|
2
|
+
<div class="actor-icon"><%= icon activity.source %></div>
|
3
|
+
<div class="activity-content">
|
4
|
+
<p><span class="actor"><%= link_to activity.source.display_name, activity.source %></span> <%= activity.content %></p>
|
5
|
+
<span class="activity-time"><%= t("muck.activities.time_ago", :time_in_words => time_ago_in_words(activity.created_at)) %></span>
|
6
|
+
<%= delete_activity(activity, :image) %>
|
7
|
+
</div>
|
8
|
+
</div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<%-
|
2
|
+
comment ||= @comment
|
3
|
+
return if comment.user.nil?
|
4
|
+
truncate = false
|
5
|
+
youtube_videos = comment.comment.scan(/\[youtube:+.+\]/)
|
6
|
+
c = comment.comment.dup.gsub(/\[youtube:+.+\]/, '')
|
7
|
+
-%>
|
8
|
+
|
9
|
+
<div id="<%= comment.dom_id %>" class="comment_holder">
|
10
|
+
<%= icon comment.user, :small, :class => 'left avatar_on_comment' %>
|
11
|
+
<div class="date_details">
|
12
|
+
<%= _("%{comment_age} ago %{user_name_link} wrote :") % {:comment_age => time_ago_in_words(comment.created_at), :user_name_link => (link_to h(comment.user.full_name), profile_path(comment.user))} %>
|
13
|
+
</div>
|
14
|
+
<div class="comment_message">
|
15
|
+
<%= sanitize(textilize(c)) %>
|
16
|
+
<%= x_comment_link(comment) -%>
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<% unless youtube_videos.empty? %>
|
20
|
+
<strong><%= pluralize youtube_videos.size, 'video' %>:</strong><br/>
|
21
|
+
<% youtube_videos.each do |o| %>
|
22
|
+
<%= tb_video_link(o.gsub!(/\[youtube\:|\]/, '')) %>
|
23
|
+
<% end
|
24
|
+
end %>
|
25
|
+
<div class="clear"></div>
|
26
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% c = comment_title.comment.dup.gsub(/\[youtube:+.+\]/, '') %>
|
2
|
+
|
3
|
+
<div id="<%= comment_title.dom_id %>" class="comment_holder">
|
4
|
+
<%= icon comment_title.user, :small, :class => 'left avatar_on_comment' %>
|
5
|
+
<div class="date_details">
|
6
|
+
<%= _("%{comment_age} ago %{user_name_link} wrote :") % {:comment_age => time_ago_in_words(comment_title.created_at),
|
7
|
+
:user_name_link => (link_to h(comment_title.user.full_name),
|
8
|
+
profile_path(comment_title.user))} %>
|
9
|
+
</div>
|
10
|
+
<div class="comment_message">
|
11
|
+
<%= sanitize(textilize(c)) %>
|
12
|
+
</div>
|
13
|
+
<div class="clear"></div>
|
14
|
+
</div>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<div id="<%= parent.dom_id %>_new_comment" class="comment-form-wrapper">
|
2
|
+
<% form_for(:comment, :url => new_comment_path_with_parent(parent), :html => { :id => "#{parent.dom_id}_comment_form", :class => "comment-form"} ) do |f| -%>
|
3
|
+
<%= f.text_area :body, :class => 'min' %>
|
4
|
+
<%= hidden_field_tag :parent_comment_id, comment.id unless comment.blank? -%>
|
5
|
+
<%= f.submit t('muck.comments.add_comment'), :class => "button" %>
|
6
|
+
<% end -%>
|
7
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class CreateComments < 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.text :body, :default => ""
|
7
|
+
t.integer :user_id, :default => 0, :null => false
|
8
|
+
t.integer :parent_id
|
9
|
+
t.integer :lft
|
10
|
+
t.integer :rgt
|
11
|
+
t.integer :is_denied, :default => 0, :null => false
|
12
|
+
t.boolean :is_reviewed, :default => false
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :comments, ["user_id"]
|
17
|
+
add_index :comments, ["commentable_id", "commentable_type"]
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.down
|
22
|
+
drop_table :comments
|
23
|
+
end
|
24
|
+
end
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Acts #:nodoc:
|
3
|
+
module MuckComment #:nodoc:
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def acts_as_muck_comment(options = {})
|
11
|
+
|
12
|
+
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
|
13
|
+
validates_presence_of :body
|
14
|
+
belongs_to :user
|
15
|
+
belongs_to :commentable, :polymorphic => true
|
16
|
+
|
17
|
+
named_scope :by_newest, :order => "created_at DESC"
|
18
|
+
named_scope :recent, lambda { { :conditions => ['created_at > ?', 1.week.ago] } }
|
19
|
+
|
20
|
+
class_eval <<-EOV
|
21
|
+
|
22
|
+
# prevents a user from submitting a crafted form that bypasses activation
|
23
|
+
attr_protected :created_at, :updated_at
|
24
|
+
EOV
|
25
|
+
|
26
|
+
include ActiveRecord::Acts::MuckComment::InstanceMethods
|
27
|
+
extend ActiveRecord::Acts::MuckComment::SingletonMethods
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# class methods
|
33
|
+
module SingletonMethods
|
34
|
+
|
35
|
+
# Helper class method to lookup all comments assigned
|
36
|
+
# to all commentable types for a given user.
|
37
|
+
def find_comments_by_user(user)
|
38
|
+
find(:all,
|
39
|
+
:conditions => ["user_id = ?", user.id],
|
40
|
+
:order => "created_at DESC"
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Helper class method to look up all comments for
|
45
|
+
# commentable class name and commentable id.
|
46
|
+
def find_comments_for_commentable(commentable_str, commentable_id)
|
47
|
+
find(:all,
|
48
|
+
:conditions => ["commentable_type = ? and commentable_id = ?", commentable_str, commentable_id],
|
49
|
+
:order => "created_at DESC"
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Helper class method to look up a commentable object
|
54
|
+
# given the commentable class name and id
|
55
|
+
def find_commentable(commentable_str, commentable_id)
|
56
|
+
commentable_str.constantize.find(commentable_id)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
# All the methods available to a record that has had <tt>acts_as_muck_comment</tt> specified.
|
62
|
+
module InstanceMethods
|
63
|
+
|
64
|
+
#helper method to check if a comment has children
|
65
|
+
def has_children?
|
66
|
+
self.children.size > 0
|
67
|
+
end
|
68
|
+
|
69
|
+
# override this method to change the way permissions are handled on comments
|
70
|
+
def can_edit?(user)
|
71
|
+
return true if check_user(user)
|
72
|
+
false
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# ActsAsCommentableWithThreading
|
2
|
+
module Acts #:nodoc:
|
3
|
+
module CommentableWithThreading #:nodoc:
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def acts_as_commentable
|
11
|
+
has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at ASC'
|
12
|
+
include Acts::CommentableWithThreading::InstanceMethods
|
13
|
+
extend Acts::CommentableWithThreading::SingletonMethods
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# This module contains class methods
|
18
|
+
module SingletonMethods
|
19
|
+
# Helper method to lookup for comments for a given object.
|
20
|
+
# This method is equivalent to obj.comments.
|
21
|
+
def find_comments_for(obj)
|
22
|
+
commentable = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
|
23
|
+
|
24
|
+
Comment.find(:all,
|
25
|
+
:conditions => ["commentable_id = ? and commentable_type = ?", obj.id, commentable],
|
26
|
+
:order => "created_at DESC"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Helper class method to lookup comments for
|
31
|
+
# the mixin commentable type written by a given user.
|
32
|
+
# This method is NOT equivalent to Comment.find_comments_for_user
|
33
|
+
def find_comments_by_user(user)
|
34
|
+
commentable = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
|
35
|
+
|
36
|
+
Comment.find(:all,
|
37
|
+
:conditions => ["user_id = ? and commentable_type = ?", user.id, commentable],
|
38
|
+
:order => "created_at DESC"
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# This module contains instance methods
|
44
|
+
module InstanceMethods
|
45
|
+
|
46
|
+
# Helper method to display only root threads, no children/replies
|
47
|
+
def root_comments
|
48
|
+
self.comments.find(:all, :conditions => {:parent_id => nil})
|
49
|
+
end
|
50
|
+
|
51
|
+
# Helper method to sort comments by date
|
52
|
+
def comments_ordered_by_submitted
|
53
|
+
Comment.find(:all,
|
54
|
+
:conditions => ["commentable_id = ? and commentable_type = ?", id, self.class.name],
|
55
|
+
:order => "created_at DESC"
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Helper method that defaults the submitted time.
|
60
|
+
def add_comment(comment)
|
61
|
+
comments << comment
|
62
|
+
end
|
63
|
+
|
64
|
+
# Determines whether or not the give user can comment on the parent object
|
65
|
+
def can_comment?(user)
|
66
|
+
return true unless user.blank?
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ActiveRecord::Base.send(:include, Acts::CommentableWithThreading)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class ActionController::Routing::RouteSet
|
2
|
+
def load_routes_with_muck_comments!
|
3
|
+
muck_comments_routes = File.join(File.dirname(__FILE__), *%w[.. .. config muck_comments_routes.rb])
|
4
|
+
add_configuration_file(muck_comments_routes) unless configuration_files.include? muck_comments_routes
|
5
|
+
load_routes_without_muck_comments!
|
6
|
+
end
|
7
|
+
alias_method_chain :load_routes!, :muck_comments
|
8
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module MuckComments
|
6
|
+
class Tasks < ::Rake::TaskLib
|
7
|
+
def initialize
|
8
|
+
define
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def define
|
13
|
+
|
14
|
+
namespace :muck do
|
15
|
+
namespace :comments do
|
16
|
+
desc "Sync required files from muck comments."
|
17
|
+
task :sync do
|
18
|
+
path = File.join(File.dirname(__FILE__), *%w[.. ..])
|
19
|
+
system "rsync -ruv #{path}/db ."
|
20
|
+
#system "rsync -ruv #{path}/public ."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
MuckComments::Tasks.new
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require 'acts_as_commentable_with_threading'
|
2
|
+
|
3
|
+
ActiveRecord::Base.class_eval { include ActiveRecord::Acts::MuckComment }
|
4
|
+
ActionController::Base.send :helper, MuckCommentsHelper
|
5
|
+
I18n.load_path += Dir[ File.join(File.dirname(__FILE__), '..', 'locales', '*.{rb,yml}') ]
|
data/locales/en.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
en:
|
2
|
+
muck:
|
3
|
+
comments:
|
4
|
+
cant_delete_comment: "You don't have permission to delete that comment"
|
5
|
+
missing_parent_id_error: "Please specify a parent object"
|
6
|
+
comment_removed: "Comment successfully removed."
|
7
|
+
create_error: "Could not create the comment {{errors}}"
|
8
|
+
add_comment: "Comment"
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{muck-comments}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Justin Ball"]
|
9
|
+
s.date = %q{2009-06-13}
|
10
|
+
s.description = %q{The comment engine for the muck system.}
|
11
|
+
s.email = %q{justinball@gmail.com}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
"MIT-LICENSE",
|
17
|
+
"README.rdoc",
|
18
|
+
"Rakefile",
|
19
|
+
"VERSION",
|
20
|
+
"app/controllers/muck/comments_controller.rb",
|
21
|
+
"app/controllers/muck/comments_controller.rb",
|
22
|
+
"app/helpers/muck_comments_helper.rb",
|
23
|
+
"app/helpers/muck_comments_helper.rb",
|
24
|
+
"app/views/activity_templates/_comment.html.erb",
|
25
|
+
"app/views/activity_templates/_comment.html.erb",
|
26
|
+
"app/views/comments/_comment.html.erb",
|
27
|
+
"app/views/comments/_comment.html.erb",
|
28
|
+
"app/views/comments/_comment_title.html.erb",
|
29
|
+
"app/views/comments/_comment_title.html.erb",
|
30
|
+
"app/views/comments/_form.html.erb",
|
31
|
+
"app/views/comments/_form.html.erb",
|
32
|
+
"config/muck_comments_routes.rb",
|
33
|
+
"config/muck_comments_routes.rb",
|
34
|
+
"db/migrate/20090613173314_create_comments.rb",
|
35
|
+
"db/migrate/20090613173314_create_comments.rb",
|
36
|
+
"install.rb",
|
37
|
+
"lib/active_record/acts/muck_comment.rb",
|
38
|
+
"lib/active_record/acts/muck_comment.rb",
|
39
|
+
"lib/acts_as_commentable_with_threading.rb",
|
40
|
+
"lib/acts_as_commentable_with_threading.rb",
|
41
|
+
"lib/muck_comments.rb",
|
42
|
+
"lib/muck_comments.rb",
|
43
|
+
"lib/muck_comments/initialize_routes.rb",
|
44
|
+
"lib/muck_comments/initialize_routes.rb",
|
45
|
+
"lib/muck_comments/tasks.rb",
|
46
|
+
"lib/muck_comments/tasks.rb",
|
47
|
+
"locales/en.yml",
|
48
|
+
"locales/en.yml",
|
49
|
+
"muck-comments.gemspec",
|
50
|
+
"pkg/muck-comments-0.1.0.gem",
|
51
|
+
"rails/init.rb",
|
52
|
+
"rails/init.rb",
|
53
|
+
"tasks/muck_comments_tasks.rake",
|
54
|
+
"tasks/muck_comments_tasks.rake",
|
55
|
+
"test/db/database.yml",
|
56
|
+
"test/db/schema.rb",
|
57
|
+
"test/factories.rb",
|
58
|
+
"test/factories.rb",
|
59
|
+
"test/functional/comments_controller_test.rb",
|
60
|
+
"test/test_helper.rb",
|
61
|
+
"test/test_helper.rb",
|
62
|
+
"test/unit/comment_test.rb",
|
63
|
+
"test/unit/commentable_test.rb",
|
64
|
+
"uninstall.rb"
|
65
|
+
]
|
66
|
+
s.has_rdoc = true
|
67
|
+
s.homepage = %q{http://github.com/jbasdf/muck_comments}
|
68
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
69
|
+
s.require_paths = ["lib"]
|
70
|
+
s.rubyforge_project = %q{muck-comments}
|
71
|
+
s.rubygems_version = %q{1.3.1}
|
72
|
+
s.summary = %q{The comment engine for the muck system}
|
73
|
+
s.test_files = [
|
74
|
+
"test/db/schema.rb",
|
75
|
+
"test/factories.rb",
|
76
|
+
"test/functional/comments_controller_test.rb",
|
77
|
+
"test/test_helper.rb",
|
78
|
+
"test/unit/comment_test.rb",
|
79
|
+
"test/unit/commentable_test.rb"
|
80
|
+
]
|
81
|
+
|
82
|
+
if s.respond_to? :specification_version then
|
83
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
84
|
+
s.specification_version = 2
|
85
|
+
|
86
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
87
|
+
s.add_runtime_dependency(%q<muck-engine>, [">= 0"])
|
88
|
+
s.add_runtime_dependency(%q<muck-users>, [">= 0"])
|
89
|
+
else
|
90
|
+
s.add_dependency(%q<muck-engine>, [">= 0"])
|
91
|
+
s.add_dependency(%q<muck-users>, [">= 0"])
|
92
|
+
end
|
93
|
+
else
|
94
|
+
s.add_dependency(%q<muck-engine>, [">= 0"])
|
95
|
+
s.add_dependency(%q<muck-users>, [">= 0"])
|
96
|
+
end
|
97
|
+
end
|
Binary file
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '/../lib/muck_comments/tasks')
|
@@ -0,0 +1,18 @@
|
|
1
|
+
sqlite3:
|
2
|
+
adapter: sqlite3
|
3
|
+
dbfile: muck_comments.sqlite3.db
|
4
|
+
sqlite3mem:
|
5
|
+
:adapter: sqlite3
|
6
|
+
:dbfile: ":memory:"
|
7
|
+
postgresql:
|
8
|
+
:adapter: postgresql
|
9
|
+
:username: postgres
|
10
|
+
:password: postgres
|
11
|
+
:database: muck_comments_test
|
12
|
+
:min_messages: ERROR
|
13
|
+
mysql:
|
14
|
+
:adapter: mysql
|
15
|
+
:host: localhost
|
16
|
+
:username: root
|
17
|
+
:password:
|
18
|
+
:database: muck_comments_test
|
data/test/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/test/factories.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class Muck::CommentsControllerTest < ActionController::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@controller = Muck::CommentsController.new
|
7
|
+
@request = ActionController::TestRequest.new
|
8
|
+
@response = ActionController::TestResponse.new
|
9
|
+
end
|
10
|
+
|
11
|
+
context "delete comment" do
|
12
|
+
setup do
|
13
|
+
@comment = Factory(:comment)
|
14
|
+
end
|
15
|
+
should "delete comment" do
|
16
|
+
assert_difference "Comment.count", -1 do
|
17
|
+
delete :destroy, { :id => @comment.to_param, :format => 'json' }
|
18
|
+
ensure_flash(/comment successfully removed/i)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "create comment" do
|
24
|
+
setup do
|
25
|
+
@user = Factory(:user)
|
26
|
+
end
|
27
|
+
should " be able to create a comment" do
|
28
|
+
assert_difference "Comment.count" do
|
29
|
+
post :create, { :type => 'User', :id => @user.id, :format => 'json', :comment => { :body => 'test' } }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$:.reject! { |e| e.include? 'TextMate' }
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
3
|
+
ENV["RAILS_ENV"] = "test"
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_support/test_case'
|
8
|
+
require 'active_record'
|
9
|
+
require 'action_controller'
|
10
|
+
require 'test_help'
|
11
|
+
require 'factory_girl'
|
12
|
+
require 'ruby-debug'
|
13
|
+
require 'mocha'
|
14
|
+
require 'redgreen' rescue LoadError
|
15
|
+
require File.expand_path(File.dirname(__FILE__) + '/factories')
|
16
|
+
require File.join(File.dirname(__FILE__), 'shoulda_macros', 'controller')
|
17
|
+
|
18
|
+
plugin_test_dir = File.dirname(__FILE__)
|
19
|
+
|
20
|
+
ActiveRecord::Base.logger = Logger.new(File.join(plugin_test_dir, "debug.log"))
|
21
|
+
|
22
|
+
ActiveRecord::Base.configurations = YAML::load(IO.read(File.join(plugin_test_dir, "db", "database.yml")))
|
23
|
+
ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem")
|
24
|
+
ActiveRecord::Migration.verbose = false
|
25
|
+
load(File.join(plugin_test_dir, "db", "schema.rb"))
|
26
|
+
|
27
|
+
require File.join(plugin_test_dir, '..', 'init')
|
28
|
+
|
29
|
+
class ActiveSupport::TestCase
|
30
|
+
self.use_transactional_fixtures = true
|
31
|
+
self.use_instantiated_fixtures = false
|
32
|
+
end
|
33
|
+
|
34
|
+
class User < ActiveRecord::Base
|
35
|
+
has_many :comments
|
36
|
+
end
|
37
|
+
|
38
|
+
class Commentable < ActiveRecord::Base
|
39
|
+
acts_as_commentable
|
40
|
+
end
|
41
|
+
|
42
|
+
class Comment < ActiveRecord::Base
|
43
|
+
acts_as_muck_comment
|
44
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "test_helper")
|
2
|
+
|
3
|
+
# some of the behavior of awesome_nested_set although does so to demonstrate the use of this gem
|
4
|
+
context "Comment" do
|
5
|
+
setup do
|
6
|
+
@user = User.create!
|
7
|
+
@comment = Comment.create!(:body => "Root comment", :user => @user)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "that is valid" do
|
11
|
+
should "have a user" do
|
12
|
+
assert_not_nil @comment.user
|
13
|
+
end
|
14
|
+
|
15
|
+
should "have a body" do
|
16
|
+
assert_not_nil @comment.body
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "not have a parent if it is a root Comment" do
|
21
|
+
assert_nil @comment.parent
|
22
|
+
end
|
23
|
+
|
24
|
+
should " be able to see how many child Comments it has" do
|
25
|
+
assert_equal @comment.children.size, 0
|
26
|
+
end
|
27
|
+
|
28
|
+
should "be able to 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
|
+
assert_equal @comment.children.size, 1
|
33
|
+
end
|
34
|
+
|
35
|
+
context "after having a child added" do
|
36
|
+
setup do
|
37
|
+
@child = Comment.create!(:body => "Child comment", :user => @user)
|
38
|
+
@child.move_to_child_of(@comment)
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be able to be referenced by its child" do
|
42
|
+
assert_equal @child.parent, @comment
|
43
|
+
end
|
44
|
+
|
45
|
+
should "be able to see its child" do
|
46
|
+
assert_equal @comment.children.first, @child
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: muck-comments
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Ball
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-13 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: muck-engine
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: muck-users
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: The comment engine for the muck system.
|
36
|
+
email: justinball@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- MIT-LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
- Rakefile
|
47
|
+
- VERSION
|
48
|
+
- app/controllers/muck/comments_controller.rb
|
49
|
+
- app/helpers/muck_comments_helper.rb
|
50
|
+
- app/views/activity_templates/_comment.html.erb
|
51
|
+
- app/views/comments/_comment.html.erb
|
52
|
+
- app/views/comments/_comment_title.html.erb
|
53
|
+
- app/views/comments/_form.html.erb
|
54
|
+
- config/muck_comments_routes.rb
|
55
|
+
- db/migrate/20090613173314_create_comments.rb
|
56
|
+
- install.rb
|
57
|
+
- lib/active_record/acts/muck_comment.rb
|
58
|
+
- lib/acts_as_commentable_with_threading.rb
|
59
|
+
- lib/muck_comments.rb
|
60
|
+
- lib/muck_comments/initialize_routes.rb
|
61
|
+
- lib/muck_comments/tasks.rb
|
62
|
+
- locales/en.yml
|
63
|
+
- muck-comments.gemspec
|
64
|
+
- pkg/muck-comments-0.1.0.gem
|
65
|
+
- rails/init.rb
|
66
|
+
- tasks/muck_comments_tasks.rake
|
67
|
+
- test/db/database.yml
|
68
|
+
- test/db/schema.rb
|
69
|
+
- test/factories.rb
|
70
|
+
- test/functional/comments_controller_test.rb
|
71
|
+
- test/test_helper.rb
|
72
|
+
- test/unit/comment_test.rb
|
73
|
+
- test/unit/commentable_test.rb
|
74
|
+
- uninstall.rb
|
75
|
+
has_rdoc: true
|
76
|
+
homepage: http://github.com/jbasdf/muck_comments
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- --charset=UTF-8
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
93
|
+
version:
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project: muck-comments
|
97
|
+
rubygems_version: 1.3.1
|
98
|
+
signing_key:
|
99
|
+
specification_version: 2
|
100
|
+
summary: The comment engine for the muck system
|
101
|
+
test_files:
|
102
|
+
- test/db/schema.rb
|
103
|
+
- test/factories.rb
|
104
|
+
- test/functional/comments_controller_test.rb
|
105
|
+
- test/test_helper.rb
|
106
|
+
- test/unit/comment_test.rb
|
107
|
+
- test/unit/commentable_test.rb
|