acts-as-taggable-on 2.4.1 → 3.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.
- checksums.yaml +4 -4
- data/.travis.yml +13 -4
- data/Appraisals +8 -4
- data/CHANGELOG.md +47 -0
- data/Gemfile +7 -1
- data/README.md +21 -11
- data/Rakefile +21 -3
- data/UPGRADING +7 -0
- data/acts-as-taggable-on.gemspec +5 -5
- data/{lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb → db/migrate/1_acts_as_taggable_on_migration.rb} +0 -0
- data/db/migrate/2_add_missing_unique_indices.rb +21 -0
- data/gemfiles/{rails_3.gemfile → rails_3.2.gemfile} +1 -2
- data/gemfiles/rails_4.0.gemfile +7 -0
- data/gemfiles/rails_4.1.gemfile +7 -0
- data/lib/acts-as-taggable-on.rb +9 -13
- data/lib/acts_as_taggable_on.rb +6 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +49 -20
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +42 -32
- data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +1 -1
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +24 -13
- data/lib/acts_as_taggable_on/engine.rb +6 -0
- data/lib/acts_as_taggable_on/tag.rb +27 -7
- data/lib/acts_as_taggable_on/taggable.rb +6 -6
- data/lib/acts_as_taggable_on/tagger.rb +6 -6
- data/lib/acts_as_taggable_on/tags_helper.rb +1 -1
- data/lib/acts_as_taggable_on/version.rb +1 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +4 -71
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +19 -19
- data/spec/acts_as_taggable_on/caching_spec.rb +77 -0
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +10 -10
- data/spec/schema.rb +25 -21
- data/spec/spec_helper.rb +9 -25
- metadata +40 -56
- data/gemfiles/rails_4.gemfile +0 -8
- data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +0 -39
- data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b46e80f19a5c7de71ec448bd0700ef672ea9639
|
4
|
+
data.tar.gz: d7c19bc3aec73a2b5d1ff08ad18cb9c85e61225c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ac4317c1fa00caa6f048d4958d830da83bae5a48d8fd2f4018918319069e9e0311b99318cfe337fcd8d23f9c37055484e1c40c1ab0ecda2c256d361315b0848
|
7
|
+
data.tar.gz: 7e29cf71dfce65f2ac65d0a10972c6b26344398278c53b088b9069ec728955e697389f496b25a8f57fd521b6349aaa2ef827caab78bf8a00c7416c9be43c21e5
|
data/.travis.yml
CHANGED
@@ -1,9 +1,18 @@
|
|
1
|
-
script: "cp spec/database.yml.sample spec/database.yml && bundle install && bundle exec rake"
|
2
1
|
rvm:
|
3
|
-
- 1.8.7
|
4
|
-
- 1.9.2
|
5
2
|
- 1.9.3
|
3
|
+
- 2.0.0
|
6
4
|
env:
|
7
5
|
- DB=sqlite3
|
8
6
|
- DB=mysql
|
9
|
-
- DB=postgresql
|
7
|
+
- DB=postgresql
|
8
|
+
gemfile:
|
9
|
+
- gemfiles/rails_3.2.gemfile
|
10
|
+
- gemfiles/rails_4.0.gemfile
|
11
|
+
- gemfiles/rails_4.1.gemfile
|
12
|
+
cache: bundler
|
13
|
+
script: bundle exec rake
|
14
|
+
before_install:
|
15
|
+
- gem install bundler
|
16
|
+
bundler_args: '--without local_development'
|
17
|
+
matrix:
|
18
|
+
fast_finish: true
|
data/Appraisals
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
appraise "rails-3" do
|
2
|
-
gem "rails", "3.2
|
1
|
+
appraise "rails-3.2" do
|
2
|
+
gem "rails", "~> 3.2"
|
3
3
|
end
|
4
4
|
|
5
|
-
appraise "rails-4" do
|
6
|
-
gem "rails", "4.0
|
5
|
+
appraise "rails-4.0" do
|
6
|
+
gem "rails", "~> 4.0"
|
7
|
+
end
|
8
|
+
|
9
|
+
appraise "rails-4.1" do
|
10
|
+
gem "rails", "~> 4.1.0.beta1"
|
7
11
|
end
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Changes are below categorized as `Features, Fixes, or Misc`.
|
2
|
+
|
3
|
+
Each change should fall into categories that would affect whether the release is major (breaking changes), minor (new behavior), or patch (bug fix). See [semver](http://semver.org/) and [pessimistic versioning](http://guides.rubygems.org/patterns/#pessimistic_version_constraint)
|
4
|
+
|
5
|
+
As such, a _Feature_ would map to either major or minor. A _bug fix_ to a patch. And _misc_ is either minor or patch, the difference being kind of fuzzy for the purposes of history. Adding tests would be patch level.
|
6
|
+
|
7
|
+
### Master [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v3.0.0...master)
|
8
|
+
|
9
|
+
* Breaking Changes
|
10
|
+
* Features
|
11
|
+
* Fixes
|
12
|
+
* Misc
|
13
|
+
|
14
|
+
### [3.0.0 / 2014-01-01](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.1...v3.0.0)
|
15
|
+
|
16
|
+
* Breaking Changes
|
17
|
+
* No longer supports Ruby 1.8.
|
18
|
+
* Features
|
19
|
+
* Supports Rails 4.1.
|
20
|
+
* Misc (TODO: expand)
|
21
|
+
* [zquest #359](https://github.com/mbleigh/acts-as-taggable-on/pull/359)
|
22
|
+
* [rsl #367](https://github.com/mbleigh/acts-as-taggable-on/pull/367)
|
23
|
+
* [ktdreyer #383](https://github.com/mbleigh/acts-as-taggable-on/pull/383)
|
24
|
+
* [cwoodcox #346](https://github.com/mbleigh/acts-as-taggable-on/pull/346)
|
25
|
+
* [mrb #421](https://github.com/mbleigh/acts-as-taggable-on/pull/421)
|
26
|
+
* [bf4 #430](https://github.com/mbleigh/acts-as-taggable-on/pull/430)
|
27
|
+
* [sanemat #368](https://github.com/mbleigh/acts-as-taggable-on/pull/368)
|
28
|
+
* [bf4 #343](https://github.com/mbleigh/acts-as-taggable-on/pull/343)
|
29
|
+
* [marclennox #429](https://github.com/mbleigh/acts-as-taggable-on/pull/429)
|
30
|
+
* [shekibobo #403](https://github.com/mbleigh/acts-as-taggable-on/pull/403)
|
31
|
+
* [ches ktdreyer #410](https://github.com/mbleigh/acts-as-taggable-on/pull/410)
|
32
|
+
* [makaroni4 #371](https://github.com/mbleigh/acts-as-taggable-on/pull/371)
|
33
|
+
* [kenzai dstosik awt #431](https://github.com/mbleigh/acts-as-taggable-on/pull/431)
|
34
|
+
* [bf4 joelcogen shekibobo aaronchi #438](https://github.com/mbleigh/acts-as-taggable-on/pull/438)
|
35
|
+
* [seuros #442](https://github.com/mbleigh/acts-as-taggable-on/pull/442)
|
36
|
+
* [bf4 #445](https://github.com/mbleigh/acts-as-taggable-on/pull/445)
|
37
|
+
* [eaglemt #446](https://github.com/mbleigh/acts-as-taggable-on/pull/446)
|
38
|
+
|
39
|
+
### 3.0.0.rc2 [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/fork-v3.0.0.rc1...fork-v3.0.0.rc2)
|
40
|
+
|
41
|
+
### 3.0.0.rc1 [changes](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.1...fork-v3.0.0.rc1)
|
42
|
+
|
43
|
+
### [2.4.1 / 2013-05-07](https://github.com/mbleigh/acts-as-taggable-on/compare/v2.4.0...v2.4.1)
|
44
|
+
|
45
|
+
* Features
|
46
|
+
* Fixes
|
47
|
+
* Misc
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# ActsAsTaggableOn
|
2
2
|
[](http://travis-ci.org/mbleigh/acts-as-taggable-on)
|
3
|
+
[](https://codeclimate.com/github/mbleigh/acts-as-taggable-on)
|
3
4
|
|
4
5
|
This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney.
|
5
6
|
It has evolved substantially since that point, but all credit goes to him for the
|
@@ -20,7 +21,7 @@ Versions 2.x are compatible with Ruby 1.8.7+ and Rails 3.
|
|
20
21
|
|
21
22
|
Versions 2.4.1 and up are compatible with Rails 4 too (thanks to arabonradar and cwoodcox).
|
22
23
|
|
23
|
-
Versions 3.x (currently unreleased) are compatible with Ruby 1.9.3+ and Rails 3 and 4.
|
24
|
+
Versions 3.x (currently unreleased) are compatible with Ruby 1.9.3+ and Rails 3 and 4. There is a [release candidate you may try](http://rubygems.org/gems/acts_as_taggable_on).
|
24
25
|
|
25
26
|
For an up-to-date roadmap, see https://github.com/mbleigh/acts-as-taggable-on/issues/milestones
|
26
27
|
|
@@ -41,21 +42,17 @@ bundle
|
|
41
42
|
#### Post Installation
|
42
43
|
|
43
44
|
```shell
|
45
|
+
# For the latest versions
|
46
|
+
rake railties:install:migrations FROM=acts_as_taggable_on_engine db:migrate
|
47
|
+
|
48
|
+
# For versions 2.4.1 and earlier
|
44
49
|
rails generate acts_as_taggable_on:migration
|
45
50
|
rake db:migrate
|
46
51
|
```
|
47
52
|
|
48
|
-
|
53
|
+
#### Upgrading
|
49
54
|
|
50
|
-
|
51
|
-
directory, you can run the specs with:
|
52
|
-
|
53
|
-
```shell
|
54
|
-
bundle
|
55
|
-
rake spec
|
56
|
-
```
|
57
|
-
|
58
|
-
If you want, add a `.ruby-version` file in the project root (and use rbenv or RVM) to work on a specific version of Ruby.
|
55
|
+
see [UPGRADING](UPGRADING)
|
59
56
|
|
60
57
|
## Usage
|
61
58
|
|
@@ -298,6 +295,19 @@ We have a long list of valued contributors. [Check them all](https://github.com/
|
|
298
295
|
|
299
296
|
* [Joost Baaij](https://github.com/tilsammans)
|
300
297
|
|
298
|
+
## Testing
|
299
|
+
|
300
|
+
Acts As Taggable On uses RSpec for its test coverage. Inside the gem
|
301
|
+
directory, you can run the specs with:
|
302
|
+
|
303
|
+
```shell
|
304
|
+
bundle
|
305
|
+
rake spec
|
306
|
+
```
|
307
|
+
|
308
|
+
You can run all the tests across all the Rails versions by running `rake appraise`. If you'd also like to [run the tests across all rubies and databases as configured for Travis CI, install and run `wwtd`](https://github.com/grosser/wwtd).
|
309
|
+
|
310
|
+
|
301
311
|
## License
|
302
312
|
|
303
313
|
See [LICENSE](https://github.com/mbleigh/acts-as-taggable-on/blob/master/LICENSE.md)
|
data/Rakefile
CHANGED
@@ -1,9 +1,27 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
|
3
|
-
require '
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
STDERR.puts "Bundler not loaded"
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Copy sample spec database.yml over if not exists'
|
9
|
+
task :copy_db_config do
|
10
|
+
cp 'spec/database.yml.sample', 'spec/database.yml'
|
11
|
+
end
|
12
|
+
|
13
|
+
task :spec => [:copy_db_config]
|
4
14
|
|
5
15
|
desc 'Default: run specs'
|
6
|
-
task :default => :spec
|
16
|
+
task :default => :spec
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'appraisal'
|
20
|
+
desc 'Run tests across gemfiles specified in Appraisals'
|
21
|
+
task :appraise => ['appraisal:cleanup', 'appraisal:install', 'appraisal']
|
22
|
+
rescue LoadError
|
23
|
+
puts "appraisal tasks not available"
|
24
|
+
end
|
7
25
|
|
8
26
|
require 'rspec/core/rake_task'
|
9
27
|
RSpec::Core::RakeTask.new do |t|
|
data/UPGRADING
ADDED
data/acts-as-taggable-on.gemspec
CHANGED
@@ -24,12 +24,12 @@ Gem::Specification.new do |gem|
|
|
24
24
|
|
25
25
|
gem.add_runtime_dependency 'rails', ['>= 3', '< 5']
|
26
26
|
|
27
|
-
gem.add_development_dependency 'rspec-rails', '2.13.0' # 2.13.1 is broken
|
28
|
-
gem.add_development_dependency 'rspec', '~> 2.6'
|
29
|
-
gem.add_development_dependency 'ammeter'
|
30
27
|
gem.add_development_dependency 'sqlite3'
|
31
28
|
gem.add_development_dependency 'mysql2', '~> 0.3.7'
|
32
29
|
gem.add_development_dependency 'pg'
|
33
|
-
|
34
|
-
gem.add_development_dependency '
|
30
|
+
|
31
|
+
gem.add_development_dependency 'rspec-rails', '2.13.0' # 2.13.1 is broken
|
32
|
+
gem.add_development_dependency 'rspec', '~> 2.6'
|
33
|
+
gem.add_development_dependency 'ammeter'
|
34
|
+
|
35
35
|
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class AddMissingUniqueIndices < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
add_index :tags, :name, unique: true
|
5
|
+
|
6
|
+
remove_index :taggings, :tag_id
|
7
|
+
remove_index :taggings, [:taggable_id, :taggable_type, :context]
|
8
|
+
add_index :taggings,
|
9
|
+
[:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
|
10
|
+
unique: true, name: 'taggings_idx'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
remove_index :tags, :name
|
15
|
+
|
16
|
+
remove_index :taggings, name: 'tagging_idx'
|
17
|
+
add_index :taggings, :tag_id
|
18
|
+
add_index :taggings, [:taggable_id, :taggable_type, :context]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/acts-as-taggable-on.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require "active_record"
|
2
2
|
require "active_record/version"
|
3
|
+
require "active_support/core_ext/module"
|
3
4
|
require "action_view"
|
5
|
+
require 'active_support/all'
|
4
6
|
|
5
7
|
require "digest/sha1"
|
6
8
|
|
7
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
-
|
9
9
|
module ActsAsTaggableOn
|
10
10
|
mattr_accessor :delimiter
|
11
11
|
@@delimiter = ','
|
@@ -49,17 +49,13 @@ require "acts_as_taggable_on/tag"
|
|
49
49
|
require "acts_as_taggable_on/tag_list"
|
50
50
|
require "acts_as_taggable_on/tags_helper"
|
51
51
|
require "acts_as_taggable_on/tagging"
|
52
|
+
require 'acts_as_taggable_on/engine'
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
ActiveRecord::Base.extend ActsAsTaggableOn::Compatibility
|
58
|
-
ActiveRecord::Base.extend ActsAsTaggableOn::Taggable
|
59
|
-
ActiveRecord::Base.send :include, ActsAsTaggableOn::Tagger
|
54
|
+
ActiveSupport.on_load(:active_record) do
|
55
|
+
extend ActsAsTaggableOn::Compatibility
|
56
|
+
extend ActsAsTaggableOn::Taggable
|
57
|
+
include ActsAsTaggableOn::Tagger
|
60
58
|
end
|
61
|
-
|
62
|
-
|
63
|
-
ActionView::Base.send :include, ActsAsTaggableOn::TagsHelper
|
59
|
+
ActiveSupport.on_load(:action_view) do
|
60
|
+
include ActsAsTaggableOn::TagsHelper
|
64
61
|
end
|
65
|
-
|
@@ -1,41 +1,69 @@
|
|
1
1
|
module ActsAsTaggableOn::Taggable
|
2
2
|
module Cache
|
3
3
|
def self.included(base)
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
# When included, conditionally adds tag caching methods when the model
|
5
|
+
# has any "cached_#{tag_type}_list" column
|
6
|
+
base.instance_eval do
|
7
|
+
# @private
|
8
|
+
def _has_tags_cache_columns?(db_columns)
|
9
|
+
db_column_names = db_columns.map(&:name)
|
10
|
+
tag_types.any? {|context|
|
11
|
+
db_column_names.include?("cached_#{context.to_s.singularize}_list")
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
# @private
|
16
|
+
def _add_tags_caching_methods
|
17
|
+
send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
|
18
|
+
extend ActsAsTaggableOn::Taggable::Cache::ClassMethods
|
19
|
+
|
20
|
+
before_save :save_cached_tag_list
|
21
|
+
|
22
|
+
initialize_tags_cache
|
23
|
+
end
|
24
|
+
|
25
|
+
# ActiveRecord::Base.columns makes a database connection and caches the calculated
|
26
|
+
# columns hash for the record as @columns. Since we don't want to add caching
|
27
|
+
# methods until we confirm the presence of a caching column, and we don't
|
28
|
+
# want to force opening a database connection when the class is loaded,
|
29
|
+
# here we intercept and cache the call to :columns as @acts_as_taggable_on_columns
|
30
|
+
# to mimic the underlying behavior. While processing this first call to columns,
|
31
|
+
# we do the caching column check and dynamically add the class and instance methods
|
32
|
+
def columns
|
33
|
+
@acts_as_taggable_on_columns ||= begin
|
34
|
+
db_columns = super
|
35
|
+
if _has_tags_cache_columns?(db_columns)
|
36
|
+
_add_tags_caching_methods
|
37
|
+
end
|
38
|
+
db_columns
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
12
42
|
end
|
13
|
-
|
14
|
-
base.initialize_acts_as_taggable_on_cache
|
15
43
|
end
|
16
|
-
|
44
|
+
|
17
45
|
module ClassMethods
|
18
|
-
def
|
46
|
+
def initialize_tags_cache
|
19
47
|
tag_types.map(&:to_s).each do |tag_type|
|
20
48
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
21
49
|
def self.caching_#{tag_type.singularize}_list?
|
22
50
|
caching_tag_list_on?("#{tag_type}")
|
23
|
-
end
|
51
|
+
end
|
24
52
|
RUBY
|
25
|
-
end
|
53
|
+
end
|
26
54
|
end
|
27
|
-
|
55
|
+
|
28
56
|
def acts_as_taggable_on(*args)
|
29
57
|
super(*args)
|
30
|
-
|
58
|
+
initialize_tags_cache
|
31
59
|
end
|
32
|
-
|
60
|
+
|
33
61
|
def caching_tag_list_on?(context)
|
34
62
|
column_names.include?("cached_#{context.to_s.singularize}_list")
|
35
63
|
end
|
36
64
|
end
|
37
|
-
|
38
|
-
module InstanceMethods
|
65
|
+
|
66
|
+
module InstanceMethods
|
39
67
|
def save_cached_tag_list
|
40
68
|
tag_types.map(&:to_s).each do |tag_type|
|
41
69
|
if self.class.send("caching_#{tag_type.singularize}_list?")
|
@@ -45,9 +73,10 @@ module ActsAsTaggableOn::Taggable
|
|
45
73
|
end
|
46
74
|
end
|
47
75
|
end
|
48
|
-
|
76
|
+
|
49
77
|
true
|
50
78
|
end
|
51
79
|
end
|
80
|
+
|
52
81
|
end
|
53
82
|
end
|
@@ -5,7 +5,7 @@ module ActsAsTaggableOn::Taggable
|
|
5
5
|
base.extend ActsAsTaggableOn::Taggable::Collection::ClassMethods
|
6
6
|
base.initialize_acts_as_taggable_on_collection
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
module ClassMethods
|
10
10
|
def initialize_acts_as_taggable_on_collection
|
11
11
|
tag_types.map(&:to_s).each do |tag_type|
|
@@ -24,16 +24,16 @@ module ActsAsTaggableOn::Taggable
|
|
24
24
|
|
25
25
|
def self.top_#{tag_type}(limit = 10)
|
26
26
|
tag_counts_on('#{tag_type}', :order => 'count desc', :limit => limit.to_i)
|
27
|
-
end
|
27
|
+
end
|
28
28
|
RUBY
|
29
|
-
end
|
29
|
+
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def acts_as_taggable_on(*args)
|
33
33
|
super(*args)
|
34
34
|
initialize_acts_as_taggable_on_collection
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def tag_counts_on(context, options = {})
|
38
38
|
all_tag_counts(options.merge({:on => context.to_s}))
|
39
39
|
end
|
@@ -86,12 +86,13 @@ module ActsAsTaggableOn::Taggable
|
|
86
86
|
group_columns = "#{ActsAsTaggableOn::Tagging.table_name}.tag_id"
|
87
87
|
|
88
88
|
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
|
89
|
-
|
90
|
-
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(
|
91
|
-
|
92
|
-
tag_scope.joins("JOIN (#{tagging_scope
|
89
|
+
scoped_select = "#{table_name}.#{primary_key}"
|
90
|
+
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{safe_to_sql(select(scoped_select))})").group(group_columns)
|
91
|
+
|
92
|
+
tag_scope = tag_scope.joins("JOIN (#{safe_to_sql(tagging_scope)}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id")
|
93
|
+
tag_scope.extending(CalculationMethods)
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
##
|
96
97
|
# Calculate the tag counts for all tags.
|
97
98
|
#
|
@@ -110,29 +111,29 @@ module ActsAsTaggableOn::Taggable
|
|
110
111
|
scope = {}
|
111
112
|
|
112
113
|
## Generate conditions:
|
113
|
-
options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
|
114
|
+
options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
|
114
115
|
|
115
116
|
start_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
|
116
117
|
end_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
|
117
|
-
|
118
|
+
|
118
119
|
taggable_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.taggable_type = ?", base_class.name])
|
119
|
-
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = ?", options
|
120
|
+
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = ?", options[:id]]) if options[:id]
|
120
121
|
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on]
|
121
|
-
|
122
|
+
|
122
123
|
tagging_conditions = [
|
123
124
|
taggable_conditions,
|
124
125
|
scope[:conditions],
|
125
126
|
start_at_conditions,
|
126
127
|
end_at_conditions
|
127
128
|
].compact.reverse
|
128
|
-
|
129
|
+
|
129
130
|
tag_conditions = [
|
130
|
-
options[:conditions]
|
131
|
+
options[:conditions]
|
131
132
|
].compact.reverse
|
132
|
-
|
133
|
+
|
133
134
|
## Generate joins:
|
134
135
|
taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id"
|
135
|
-
taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'" unless descends_from_active_record? # Current model is STI descendant, so add type checking to the join condition
|
136
|
+
taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'" unless descends_from_active_record? # Current model is STI descendant, so add type checking to the join condition
|
136
137
|
|
137
138
|
tagging_joins = [
|
138
139
|
taggable_join,
|
@@ -144,10 +145,10 @@ module ActsAsTaggableOn::Taggable
|
|
144
145
|
|
145
146
|
## Generate scope:
|
146
147
|
tagging_scope = ActsAsTaggableOn::Tagging.select("#{ActsAsTaggableOn::Tagging.table_name}.tag_id, COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) AS tags_count")
|
147
|
-
tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*, #{ActsAsTaggableOn::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit])
|
148
|
+
tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*, #{ActsAsTaggableOn::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit])
|
148
149
|
|
149
150
|
# Joins and conditions
|
150
|
-
tagging_joins.each { |join| tagging_scope = tagging_scope.joins(join) }
|
151
|
+
tagging_joins.each { |join| tagging_scope = tagging_scope.joins(join) }
|
151
152
|
tagging_conditions.each { |condition| tagging_scope = tagging_scope.where(condition) }
|
152
153
|
|
153
154
|
tag_joins.each { |join| tag_scope = tag_scope.joins(join) }
|
@@ -156,29 +157,38 @@ module ActsAsTaggableOn::Taggable
|
|
156
157
|
# GROUP BY and HAVING clauses:
|
157
158
|
at_least = sanitize_sql(["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) >= ?", options.delete(:at_least)]) if options[:at_least]
|
158
159
|
at_most = sanitize_sql(["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) <= ?", options.delete(:at_most)]) if options[:at_most]
|
159
|
-
having = ["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) > 0", at_least, at_most].compact.join(' AND ')
|
160
|
+
having = ["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) > 0", at_least, at_most].compact.join(' AND ')
|
160
161
|
|
161
162
|
group_columns = "#{ActsAsTaggableOn::Tagging.table_name}.tag_id"
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
res = "NULL" if res.blank?
|
164
|
+
unless options[:id]
|
165
|
+
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
|
166
|
+
scoped_select = "#{table_name}.#{primary_key}"
|
167
|
+
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{safe_to_sql(select(scoped_select))})")
|
168
|
+
end
|
169
169
|
|
170
|
-
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{res})")
|
171
170
|
tagging_scope = tagging_scope.group(group_columns).having(having)
|
172
171
|
|
173
|
-
tag_scope = tag_scope.joins("JOIN (#{tagging_scope
|
174
|
-
tag_scope
|
172
|
+
tag_scope = tag_scope.joins("JOIN (#{safe_to_sql(tagging_scope)}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id")
|
173
|
+
tag_scope.extending(CalculationMethods)
|
174
|
+
end
|
175
|
+
|
176
|
+
def safe_to_sql(relation)
|
177
|
+
connection.respond_to?(:unprepared_statement) ? connection.unprepared_statement{relation.to_sql} : relation.to_sql
|
175
178
|
end
|
176
179
|
end
|
177
|
-
|
180
|
+
|
178
181
|
module InstanceMethods
|
179
182
|
def tag_counts_on(context, options={})
|
180
183
|
self.class.tag_counts_on(context, options.merge(:id => id))
|
181
184
|
end
|
182
185
|
end
|
186
|
+
|
187
|
+
module CalculationMethods
|
188
|
+
def count
|
189
|
+
# https://github.com/rails/rails/commit/da9b5d4a8435b744fcf278fffd6d7f1e36d4a4f2
|
190
|
+
super(:all)
|
191
|
+
end
|
192
|
+
end
|
183
193
|
end
|
184
|
-
end
|
194
|
+
end
|