adva_comments 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/app/controllers/admin/comments_controller.rb +0 -16
- data/app/controllers/comments_controller.rb +0 -1
- data/app/helpers/admin/comments_helper.rb +1 -12
- data/app/helpers/comments_helper.rb +4 -4
- data/app/models/comment.rb +0 -4
- data/app/views/admin/comments/index.html.erb +19 -32
- data/app/views/admin/sites/_comments_settings.html.erb +3 -3
- data/config/initializers/article.rb +1 -1
- data/config/initializers/section.rb +1 -1
- data/config/initializers/site.rb +1 -1
- data/lib/adva_comments/version.rb +1 -1
- data/lib/adva_comments.rb +7 -0
- data/vendor/gems/has_counter/.gitignore +17 -0
- data/vendor/gems/has_counter/Gemfile +4 -0
- data/vendor/gems/has_counter/LICENSE +22 -0
- data/vendor/gems/has_counter/MIT-LICENSE +20 -0
- data/vendor/gems/has_counter/README.markdown +64 -0
- data/vendor/gems/has_counter/README.md +29 -0
- data/vendor/gems/has_counter/Rakefile +2 -0
- data/vendor/gems/has_counter/db/migrate/20080601194338_create_counters_table.rb.rb +13 -0
- data/vendor/gems/has_counter/has_counter.gemspec +17 -0
- data/vendor/gems/has_counter/lib/active_record/has_counter.rb +67 -0
- data/vendor/gems/has_counter/lib/counter.rb +23 -0
- data/vendor/gems/has_counter/lib/has_counter/version.rb +3 -0
- data/vendor/gems/has_counter/lib/has_counter.rb +4 -0
- data/vendor/gems/has_counter/spec/has_counter.sqlite3.db +0 -0
- data/vendor/gems/has_counter/spec/has_counter_spec.rb +55 -0
- data/vendor/gems/has_counter/spec/spec_helper.rb +117 -0
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e277ce05bae7382170abf884c567b814fd55a5f4eb985914935322666e1f5c0d
|
4
|
+
data.tar.gz: db622f439cb5c50396a93216525d9827bbf02d5b214e46d16cca2226f81ddc71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 748876a86dfebb62217971001ae162a2929463d67f0c4abf8055b63a3e10554e4f6f529904bd358aaa6adbc02aedb8670197fae701bda7df5cdab5df9a8b05f9
|
7
|
+
data.tar.gz: 40ca52aefa6404fac125d8ebb857fe39300802118a84a2975256cecb676f5286070f77fac39c1cbbc1b3aa30fb6ba1ef5ffd3ac7753ca976e3a53d8d5c362144
|
@@ -56,22 +56,6 @@ class Admin::CommentsController < Admin::BaseController
|
|
56
56
|
@comment = Comment.find(params[:id])
|
57
57
|
end
|
58
58
|
|
59
|
-
def filter_options options
|
60
|
-
case params[:filter]
|
61
|
-
when 'state'
|
62
|
-
params[:state] == 'approved' ? options[:conditions] = "approved = '1'" : options[:conditions] = "approved = '0'"
|
63
|
-
when 'body'
|
64
|
-
options[:conditions] = Comment.send(:sanitize_sql, ["LOWER(body) LIKE :query", {:query => "%#{params[:query].downcase}%"}])
|
65
|
-
when 'author_name'
|
66
|
-
options[:conditions] = Comment.send(:sanitize_sql, ["LOWER(author_name) LIKE :query", {:query => "%#{params[:query].downcase}%"}])
|
67
|
-
when 'author_email'
|
68
|
-
options[:conditions] = Comment.send(:sanitize_sql, ["LOWER(author_email) LIKE :query", {:query => "%#{params[:query].downcase}%"}])
|
69
|
-
when 'author_homepage'
|
70
|
-
options[:conditions] = Comment.send(:sanitize_sql, ["LOWER(author_homepage) LIKE :query", {:query => "%#{params[:query].downcase}%"}])
|
71
|
-
end
|
72
|
-
options
|
73
|
-
end
|
74
|
-
|
75
59
|
def postback_spaminess
|
76
60
|
if @comment.approved_changed? and @site.respond_to?(:spam_engine)
|
77
61
|
spaminess = @comment.approved? ? :ham : :spam
|
@@ -11,17 +11,6 @@ module Admin
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def comments_filter_options
|
15
|
-
options = I18n.t(:'adva.comments.filter.options')
|
16
|
-
|
17
|
-
[[options[:all], 'all'],
|
18
|
-
[options[:state], 'state'],
|
19
|
-
[options[:body], 'body'],
|
20
|
-
[options[:author_name], 'author_name'],
|
21
|
-
[options[:author_email], 'author_email'],
|
22
|
-
[options[:author_url], 'author_homepage']]
|
23
|
-
end
|
24
|
-
|
25
14
|
def comments_state_options
|
26
15
|
options = I18n.t(:'adva.comments.state.options')
|
27
16
|
|
@@ -29,4 +18,4 @@ module Admin
|
|
29
18
|
[options[:unapproved], 'unapproved']]
|
30
19
|
end
|
31
20
|
end
|
32
|
-
end
|
21
|
+
end
|
@@ -2,7 +2,7 @@ module CommentsHelper
|
|
2
2
|
def comments_feed_title(*owners)
|
3
3
|
options = owners.extract_options!
|
4
4
|
separator = options[:separator] || ' » '
|
5
|
-
|
5
|
+
'Comments: ' + owners.compact.uniq.map(&:title).join(separator)
|
6
6
|
end
|
7
7
|
|
8
8
|
methods = %w(admin_comments_path admin_comment_path
|
@@ -21,7 +21,7 @@ module CommentsHelper
|
|
21
21
|
def link_to_content_comments_count(content, options = {:total => true})
|
22
22
|
total = content.comments_count
|
23
23
|
approved = content.approved_comments_count
|
24
|
-
return options[:alt] ||
|
24
|
+
return options[:alt] || "None" if approved == 0
|
25
25
|
text = if total == approved or !options[:total]
|
26
26
|
"#{approved.to_s.rjust(2, '0')}"
|
27
27
|
else
|
@@ -37,7 +37,7 @@ module CommentsHelper
|
|
37
37
|
return unless content.approved_comments_count > 0 || content.accept_comments?
|
38
38
|
|
39
39
|
text = t(text) if text.is_a?(Symbol)
|
40
|
-
text ||=
|
40
|
+
text ||= pluralize(content.approved_comments_count, "comment")
|
41
41
|
options.merge! :anchor => (comment ? dom_id(comment) : 'comments')
|
42
42
|
link_to text, [content.section, content], options
|
43
43
|
end
|
@@ -49,7 +49,7 @@ module CommentsHelper
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def link_to_remote_comment_preview
|
52
|
-
link_to(
|
52
|
+
link_to("Preview", preview_comments_path, :id => 'preview_comment', :style => "display:none;") +
|
53
53
|
image_tag('adva_cms/indicator.gif', :alt => '', :id => 'comment_preview_spinner', :style => 'display:none;')
|
54
54
|
end
|
55
55
|
|
data/app/models/comment.rb
CHANGED
@@ -26,10 +26,6 @@ class Comment < ActiveRecord::Base
|
|
26
26
|
end
|
27
27
|
|
28
28
|
filtered_column :body
|
29
|
-
filters_attributes :sanitize => :body_html
|
30
|
-
|
31
|
-
has_filter :text => { :attributes => [:body] },
|
32
|
-
:state => { :states => [:approved, :unapproved] }
|
33
29
|
|
34
30
|
belongs_to :site
|
35
31
|
belongs_to :section
|
@@ -1,42 +1,29 @@
|
|
1
|
-
<%= content_for :sidebar do %>
|
2
|
-
<!--
|
3
|
-
<div class="tabs">
|
4
|
-
<ul>
|
5
|
-
<li class="active"><a href="#filters" onclick="return false;"><%= t(:'adva.titles.filters') %></a></li>
|
6
|
-
</ul>
|
7
|
-
<div class="tab active" id="tab_filters">
|
8
|
-
<%= filter_for(Comment) %>
|
9
|
-
</div>
|
10
|
-
</div>
|
11
|
-
-->
|
12
|
-
<% end %>
|
13
|
-
|
14
1
|
<%= will_paginate @comments %>
|
15
2
|
|
16
3
|
<ul id="comments_list">
|
17
4
|
<% if @comments.present? %>
|
18
5
|
<% @comments.each do |comment, i| %>
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
6
|
+
<li class="<%= cycle 'alt', '' %>" id="<%= dom_id(comment) %>">
|
7
|
+
<h4><%= link_to comment.commentable.title, [comment.commentable.section, comment.commentable] if comment.commentable %></h4>
|
8
|
+
<div class="actions">
|
9
|
+
<%= comment.approved? ?
|
10
|
+
link_to(t(:'adva.comments.links.unapprove'), admin_comment_path(comment, "comment[approved]" => 0, :return_to => request.fullpath), :class => 'text', :method => :put) :
|
11
|
+
link_to(t(:'adva.comments.links.approve'), admin_comment_path(comment, "comment[approved]" => 1, :return_to => request.fullpath), :class => 'text', :method => :put) %>
|
12
|
+
<%= link_to_edit(comment, :url => edit_admin_comment_path(comment, :return_to => request.fullpath)) %>
|
13
|
+
<%= link_to_delete(comment, :url => admin_comment_path(comment, :return_to => request.fullpath)) %>
|
14
|
+
</div>
|
15
|
+
<cite>
|
16
|
+
<%= link_to_author(comment) %>
|
17
|
+
<%= "(#{comment.author_email})" %>
|
18
|
+
<%= t(:'adva.comments.said_time_ago', :time => time_ago_in_words(comment.created_at)) %>
|
19
|
+
</cite>
|
20
|
+
<blockquote>
|
21
|
+
<%= strip_tags(comment.body) %>
|
22
|
+
</blockquote>
|
23
|
+
</li>
|
37
24
|
<% end %>
|
38
25
|
<% else %>
|
39
|
-
<li class="alt"><%=
|
26
|
+
<li class="alt"><%= t(:'adva.comments.no_comments') %></li>
|
40
27
|
<% end %>
|
41
28
|
</ul>
|
42
29
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<h2><%= t(:'adva.titles.comments') %></h2>
|
2
2
|
|
3
3
|
<% f.field_set :comments_settings do %>
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
<% column do %>
|
5
|
+
<%= f.select :comment_filter, filter_options, {}, :label => true, :hint => :'adva.comments.hints.comments_filter' %>
|
6
|
+
<% end %>
|
7
7
|
<% end %>
|
@@ -6,7 +6,7 @@ ActiveSupport::Reloader.to_prepare do
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
class ArticleFormBuilder < ExtensibleFormBuilder
|
9
|
+
class ArticleFormBuilder < Adva::ExtensibleFormBuilder
|
10
10
|
after(:article, :filter) do |f|
|
11
11
|
render :partial => 'admin/articles/comments_settings', :locals => { :f => f }
|
12
12
|
end
|
data/config/initializers/site.rb
CHANGED
data/lib/adva_comments.rb
CHANGED
@@ -5,6 +5,13 @@ require "active_record/has_many_comments"
|
|
5
5
|
require "action_controller/acts_as_commentable"
|
6
6
|
require "invisible_captcha"
|
7
7
|
|
8
|
+
# load vendored gems
|
9
|
+
Dir["#{File.expand_path("#{__dir__}/../vendor/gems")}/**/lib"].each do |vendored_gem_path|
|
10
|
+
$: << vendored_gem_path
|
11
|
+
end
|
12
|
+
|
13
|
+
require "has_counter"
|
14
|
+
|
8
15
|
module AdvaComments
|
9
16
|
class Engine < Rails::Engine
|
10
17
|
initializer "add assets to precompilation list" do |app|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Micah Geisel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Sven Fuchs
|
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.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
## Has Counter
|
2
|
+
|
3
|
+
Allows to cache the number of records for a `has_many` association.
|
4
|
+
|
5
|
+
Yes, this is the same thing you can do by setting the `:counter_cache` option
|
6
|
+
on the corresponding `belongs_to` association.
|
7
|
+
|
8
|
+
The reason for reinventing the `counter_cache` wheel here is that
|
9
|
+
`counter_cache` is a bit inflexible. We need to "hardcode" the counter_cache
|
10
|
+
column and thereby clutter the schema. This can especially get annoying in
|
11
|
+
combo with STI, when - e.g. one subclass needs some `counter_caches` that are
|
12
|
+
specific to this subclass only.
|
13
|
+
|
14
|
+
Instead, with `has_counter`, counters can be separated into an external table
|
15
|
+
with generic column names.
|
16
|
+
|
17
|
+
The ActiveRecord `counter_cache` mechanism also requires to put the
|
18
|
+
`:counter_cache` directive on the `belongs_to` association of the counted class,
|
19
|
+
which adds some tight coupleing that we might want to avoid.
|
20
|
+
|
21
|
+
Instead, with `has_counter`, we can observe the counted class and update our
|
22
|
+
counters "from the outside", so the counted class does not need to know about
|
23
|
+
the fact that somebody else keeps a counter on it.
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
class User
|
28
|
+
has_counter :posts
|
29
|
+
end
|
30
|
+
|
31
|
+
This will add a `has_one :post_counter` association to the User model as well
|
32
|
+
as the appropriate callbacks for creating the initial counter object when a
|
33
|
+
User is created and in/decrementing the counter when a Post is created or
|
34
|
+
destroyed.
|
35
|
+
|
36
|
+
For convenience it also adds a `posts_count` method to the User model that you
|
37
|
+
should use to read the actual numeric count value.
|
38
|
+
|
39
|
+
In case you need that you can use the following methods to manually
|
40
|
+
in/decrement or set the counter value:
|
41
|
+
|
42
|
+
user.posts_counter.increment! # increments and saves the counter
|
43
|
+
user.posts_counter.decrement! # decrement and saves the counter
|
44
|
+
user.posts_counter.set(5) # sets the counter to 5 and saves it
|
45
|
+
|
46
|
+
## Limitations
|
47
|
+
|
48
|
+
There are quite some. The above example expects that there is the following
|
49
|
+
association on the Posts model:
|
50
|
+
|
51
|
+
class Post
|
52
|
+
belongs_to :user
|
53
|
+
end
|
54
|
+
|
55
|
+
`User.has_counter :posts` also expects that a Post model exists and that this
|
56
|
+
is the one you want to count. At this point you can **not** count arbitrary
|
57
|
+
associations like:
|
58
|
+
|
59
|
+
class Post
|
60
|
+
has_counter :approved_comments # with special conditions/callbacks
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# HasCounter
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'has_counter'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install has_counter
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateCountersTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :counters, :force => true do |t|
|
4
|
+
t.references :owner, :polymorphic => true
|
5
|
+
t.string :name, :limit => 25
|
6
|
+
t.integer :count, :default => 0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table :counters
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/has_counter/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Micah Geisel"]
|
6
|
+
gem.email = ["micah@botandrose.com"]
|
7
|
+
gem.description = %q{TODO: Write a gem description}
|
8
|
+
gem.summary = %q{TODO: Write a gem summary}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "has_counter"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = HasCounter::VERSION
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module HasCounter
|
3
|
+
class << self
|
4
|
+
def included(base)
|
5
|
+
base.extend ActMacro
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ActMacro
|
10
|
+
def has_counter(*names)
|
11
|
+
options = names.extract_options!
|
12
|
+
callbacks = options[:callbacks] || { :after_create => :increment!, :after_destroy => :decrement! }
|
13
|
+
|
14
|
+
class_attribute :"update_counters"
|
15
|
+
self.update_counters ||= {}
|
16
|
+
|
17
|
+
names.each do |name|
|
18
|
+
counter_name = :"#{name}_counter"
|
19
|
+
owner_name = options[:as] || self.name.demodulize.underscore
|
20
|
+
class_name = options[:class_name] || name
|
21
|
+
|
22
|
+
define_method :"#{name}_count" do
|
23
|
+
send(counter_name).count
|
24
|
+
end
|
25
|
+
|
26
|
+
has_one counter_name, -> { where(name: name) },
|
27
|
+
as: :owner,
|
28
|
+
class_name: "Counter",
|
29
|
+
dependent: :delete
|
30
|
+
|
31
|
+
# create the counter lazily upon first access
|
32
|
+
class_eval <<-code, __FILE__, __LINE__
|
33
|
+
prepend Module.new {
|
34
|
+
def #{counter_name}(force_reload = false)
|
35
|
+
reload_#{counter_name} if force_reload
|
36
|
+
result = super()
|
37
|
+
if result.nil?
|
38
|
+
Counter.create!(:owner => self, :name => #{name.to_s.inspect})
|
39
|
+
reload_#{counter_name}
|
40
|
+
result = super()
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
}
|
45
|
+
code
|
46
|
+
|
47
|
+
# Wire up the counted class so that it updates our counter, basically
|
48
|
+
# an anonymous callback/observer pattern
|
49
|
+
target = class_name.to_s.classify.constantize
|
50
|
+
callbacks.keys.each do |callback|
|
51
|
+
target.send callback do |record|
|
52
|
+
owner = record.send(owner_name) if record.respond_to?(owner_name)
|
53
|
+
# do not update the counter when counter's owner (e.g. article) is not frozen (deleted)
|
54
|
+
if self === owner && !owner.frozen? && record.class == target
|
55
|
+
method = callbacks[callback]
|
56
|
+
method = method.call(record) if Proc === method
|
57
|
+
counter = owner.send(counter_name) if method
|
58
|
+
counter.send method if counter && method
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Counter < ActiveRecord::Base
|
2
|
+
belongs_to :owner, :polymorphic => true
|
3
|
+
|
4
|
+
def increment!
|
5
|
+
set count + 1
|
6
|
+
end
|
7
|
+
|
8
|
+
def increment_by!(value)
|
9
|
+
set count + value
|
10
|
+
end
|
11
|
+
|
12
|
+
def decrement!
|
13
|
+
set count - 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def decrement_by!(value)
|
17
|
+
set count - value
|
18
|
+
end
|
19
|
+
|
20
|
+
def set(value)
|
21
|
+
update! count: value
|
22
|
+
end
|
23
|
+
end
|
Binary file
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/spec_helper.rb")
|
2
|
+
|
3
|
+
describe "has_counter:", "using default after_create and after_destroy callbacks" do
|
4
|
+
before :each do
|
5
|
+
Counter.delete_all
|
6
|
+
CounterSpec::Content.delete_all
|
7
|
+
CounterSpec::Comment.delete_all
|
8
|
+
|
9
|
+
@content = CounterSpec::Content.create! :title => 'first content'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "instantiates a counter" do
|
13
|
+
@content.comments.create! :text => 'first comment'
|
14
|
+
@content.comments_counter.should_not be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "increments the counter on creation" do
|
18
|
+
@content.comments.create! :text => 'first comment'
|
19
|
+
@content.comments_count.should == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
it "decrements the counter on deletion" do
|
23
|
+
@comment = @content.comments.create! :text => 'first comment'
|
24
|
+
@comment.destroy
|
25
|
+
@content.comments_count.should == 0
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "has_counter:", "using a method name as after_create and after_destroy callbacks" do
|
30
|
+
before :each do
|
31
|
+
Counter.delete_all
|
32
|
+
CounterSpec::Content.delete_all
|
33
|
+
CounterSpec::Comment.delete_all
|
34
|
+
|
35
|
+
@content = CounterSpec::Content.create! :title => 'first content'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "instantiates a counter" do
|
39
|
+
@content.comments.create! :text => 'first comment'
|
40
|
+
@content.approved_comments_counter.should_not be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "increments the counter on creation" do
|
44
|
+
@content.comments.create! :text => 'first comment', :approved => 1
|
45
|
+
@content.approved_comments_count.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it "decrements the counter on deletion" do
|
49
|
+
@comment = @content.comments.create! :text => 'first comment', :approved => 1
|
50
|
+
@content.approved_comments_count.should == 1
|
51
|
+
@comment.destroy
|
52
|
+
@content.reload
|
53
|
+
@content.approved_comments_count.should == 0
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) + '/../lib/'
|
2
|
+
|
3
|
+
ENV["RAILS_ENV"] = "test"
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'active_record'
|
7
|
+
|
8
|
+
ActiveRecord::Base.class_eval do
|
9
|
+
class << self
|
10
|
+
# no peeping toms (aka observers) wanted here
|
11
|
+
alias_method :dont_instantiate_observers, :instantiate_observers
|
12
|
+
def instantiate_observers; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
17
|
+
require 'spec'
|
18
|
+
require 'spec/rails'
|
19
|
+
|
20
|
+
config = {'adapter' => 'sqlite3', 'dbfile' => File.dirname(__FILE__) + '/has_counter.sqlite3.db'}
|
21
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/has_counter.spec.log')
|
22
|
+
ActiveRecord::Base.establish_connection(config)
|
23
|
+
|
24
|
+
require 'counter'
|
25
|
+
unless Counter.table_exists?
|
26
|
+
ActiveRecord::Migration.verbose = false
|
27
|
+
ActiveRecord::Schema.define(:version => 1) do
|
28
|
+
create_table :counters, :force => true do |t|
|
29
|
+
t.references :owner, :polymorphic => true
|
30
|
+
t.string :name, :limit => 25
|
31
|
+
t.integer :count, :default => 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module CounterSpec
|
37
|
+
class Comment < ActiveRecord::Base
|
38
|
+
self.table_name = 'comments'
|
39
|
+
|
40
|
+
belongs_to :content
|
41
|
+
after_save :update_commentable
|
42
|
+
after_destroy :update_commentable
|
43
|
+
|
44
|
+
unless table_exists?
|
45
|
+
ActiveRecord::Migration.verbose = false
|
46
|
+
ActiveRecord::Schema.define(:version => 1) do
|
47
|
+
create_table :comments, :force => true do |t|
|
48
|
+
t.references :content
|
49
|
+
t.text :text
|
50
|
+
t.integer :approved
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def unapproved?
|
56
|
+
!approved?
|
57
|
+
end
|
58
|
+
|
59
|
+
def just_approved?
|
60
|
+
approved? && approved_changed?
|
61
|
+
end
|
62
|
+
|
63
|
+
def just_unapproved?
|
64
|
+
!approved? && approved_changed?
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_commentable
|
68
|
+
content.after_comment_update(self)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Content < ActiveRecord::Base
|
73
|
+
self.table_name = 'contents'
|
74
|
+
|
75
|
+
has_many :comments
|
76
|
+
|
77
|
+
has_counter :comments,
|
78
|
+
:class_name => 'CounterSpec::Comment'
|
79
|
+
|
80
|
+
has_counter :approved_comments,
|
81
|
+
:class_name => 'CounterSpec::Comment',
|
82
|
+
:after_create => false,
|
83
|
+
:after_destroy => false
|
84
|
+
# :after_destroy => lambda{|record|
|
85
|
+
# :decrement! if record.approved?
|
86
|
+
# },
|
87
|
+
# :after_save => lambda{|record|
|
88
|
+
# record.just_approved? && :increment! or
|
89
|
+
# record.just_unapproved? && :decrement!
|
90
|
+
# }
|
91
|
+
|
92
|
+
def after_comment_update(comment)
|
93
|
+
method = if comment.frozen? && comment.approved?
|
94
|
+
:decrement!
|
95
|
+
elsif comment.just_approved?
|
96
|
+
:increment!
|
97
|
+
elsif comment.just_unapproved?
|
98
|
+
:decrement!
|
99
|
+
end
|
100
|
+
approved_comments_counter.send method if method
|
101
|
+
end
|
102
|
+
|
103
|
+
unless table_exists?
|
104
|
+
ActiveRecord::Migration.verbose = false
|
105
|
+
ActiveRecord::Schema.define(:version => 1) do
|
106
|
+
create_table :contents, :force => true do |t|
|
107
|
+
t.string :title, :limit => 50
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adva_comments
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: validates_email_format_of
|
@@ -97,6 +97,22 @@ files:
|
|
97
97
|
- test/unit/models/comment_test.rb
|
98
98
|
- test/unit/models/commentable_test.rb
|
99
99
|
- test/unit/observers/activities_comment_observer_test.rb
|
100
|
+
- vendor/gems/has_counter/.gitignore
|
101
|
+
- vendor/gems/has_counter/Gemfile
|
102
|
+
- vendor/gems/has_counter/LICENSE
|
103
|
+
- vendor/gems/has_counter/MIT-LICENSE
|
104
|
+
- vendor/gems/has_counter/README.markdown
|
105
|
+
- vendor/gems/has_counter/README.md
|
106
|
+
- vendor/gems/has_counter/Rakefile
|
107
|
+
- vendor/gems/has_counter/db/migrate/20080601194338_create_counters_table.rb.rb
|
108
|
+
- vendor/gems/has_counter/has_counter.gemspec
|
109
|
+
- vendor/gems/has_counter/lib/active_record/has_counter.rb
|
110
|
+
- vendor/gems/has_counter/lib/counter.rb
|
111
|
+
- vendor/gems/has_counter/lib/has_counter.rb
|
112
|
+
- vendor/gems/has_counter/lib/has_counter/version.rb
|
113
|
+
- vendor/gems/has_counter/spec/has_counter.sqlite3.db
|
114
|
+
- vendor/gems/has_counter/spec/has_counter_spec.rb
|
115
|
+
- vendor/gems/has_counter/spec/spec_helper.rb
|
100
116
|
homepage: ''
|
101
117
|
licenses: []
|
102
118
|
metadata: {}
|
@@ -115,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
131
|
- !ruby/object:Gem::Version
|
116
132
|
version: '0'
|
117
133
|
requirements: []
|
118
|
-
rubygems_version: 3.2.
|
134
|
+
rubygems_version: 3.2.32
|
119
135
|
signing_key:
|
120
136
|
specification_version: 4
|
121
137
|
summary: Engine for Adva CMS commenting component
|