acts-as-taggable-on 2.0.6 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/CHANGELOG +10 -0
- data/Gemfile +2 -9
- data/Guardfile +5 -0
- data/README.rdoc +47 -63
- data/Rakefile +9 -55
- data/acts-as-taggable-on.gemspec +28 -0
- data/lib/acts-as-taggable-on/version.rb +4 -0
- data/lib/acts-as-taggable-on.rb +7 -3
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +4 -4
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +38 -43
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +81 -30
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +7 -3
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +23 -15
- data/lib/acts_as_taggable_on/tag.rb +21 -12
- data/lib/acts_as_taggable_on/{acts_as_taggable_on.rb → taggable.rb} +6 -5
- data/lib/acts_as_taggable_on/tagging.rb +12 -2
- data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
- data/lib/acts_as_taggable_on/utils.rb +34 -0
- data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +9 -2
- data/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb +3 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +242 -54
- data/spec/acts_as_taggable_on/tag_list_spec.rb +4 -0
- data/spec/acts_as_taggable_on/tag_spec.rb +52 -13
- data/spec/acts_as_taggable_on/taggable_spec.rb +131 -35
- data/spec/acts_as_taggable_on/tagger_spec.rb +14 -0
- data/spec/acts_as_taggable_on/tagging_spec.rb +2 -5
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +16 -0
- data/spec/acts_as_taggable_on/utils_spec.rb +21 -0
- data/spec/database.yml.sample +4 -2
- data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +22 -0
- data/spec/models.rb +14 -1
- data/spec/schema.rb +13 -0
- data/spec/spec_helper.rb +27 -6
- data/uninstall.rb +1 -0
- metadata +136 -51
- data/VERSION +0 -1
- data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
- data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
- data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -8
- data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -17
- data/lib/acts_as_taggable_on/compatibility/postgresql.rb +0 -44
- data/spec/database.yml +0 -17
- /data/lib/acts_as_taggable_on/{acts_as_tagger.rb → tagger.rb} +0 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 2011-08-21
|
2
|
+
* escape _ and % for mysql and postgres (@tilsammans)
|
3
|
+
* Now depends on mysql2 gem
|
4
|
+
* tagged_with :any is chainable now (@jeffreyiacono)
|
5
|
+
* tagged_with(nil) returns scoped object
|
6
|
+
* Case-insensitivity for TaggedModel.tagged_with for PostgreSQL database
|
7
|
+
* tagged_with(' ') returns scoped object
|
8
|
+
* remove warning for rails 3.1 about class_inheritable_attribute
|
9
|
+
* use ActiveRecord migration_number to avoid clashs (@atd)
|
10
|
+
|
1
11
|
== 2010-02-17
|
2
12
|
* Converted the plugin to be compatible with Rails3
|
3
13
|
|
data/Gemfile
CHANGED
data/Guardfile
ADDED
data/README.rdoc
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
= ActsAsTaggableOn
|
2
|
+
{<img src="https://secure.travis-ci.org/mbleigh/acts-as-taggable-on.png" />}[http://travis-ci.org/mbleigh/acts-as-taggable-on]
|
2
3
|
|
3
4
|
This plugin was originally based on Acts as Taggable on Steroids by Jonathan Viney.
|
4
5
|
It has evolved substantially since that point, but all credit goes to him for the
|
@@ -17,35 +18,15 @@ was used.
|
|
17
18
|
|
18
19
|
=== Rails 2.3.x
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
==== Plugin
|
23
|
-
|
24
|
-
Acts As Taggable On is available both as a gem and as a traditional plugin. For the
|
25
|
-
traditional plugin you can install like so:
|
26
|
-
|
27
|
-
script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git
|
28
|
-
|
29
|
-
Acts As Taggable On is also available as a gem plugin using Rails 2.1's gem dependencies.
|
30
|
-
To install the gem, add this to your config/environment.rb:
|
31
|
-
|
32
|
-
config.gem "acts-as-taggable-on", :source => "http://gemcutter.org", :version => '2.0.0.rc1'
|
33
|
-
|
34
|
-
After that, you can run "rake gems:install" to install the gem if you don't already have it.
|
35
|
-
|
36
|
-
==== Post Installation
|
37
|
-
|
38
|
-
1. script/generate acts_as_taggable_on_migration
|
39
|
-
2. rake db:migrate
|
21
|
+
To use it, add it to your Gemfile:
|
40
22
|
|
41
|
-
|
23
|
+
gem 'acts-as-taggable-on', '~>2.1.0'
|
42
24
|
|
43
|
-
|
44
|
-
and Jelle Vandebeeck.
|
25
|
+
=== Rails 3.x
|
45
26
|
|
46
27
|
To use it, add it to your Gemfile:
|
47
|
-
|
48
|
-
gem 'acts-as-taggable-on'
|
28
|
+
|
29
|
+
gem 'acts-as-taggable-on', '~>2.2.0'
|
49
30
|
|
50
31
|
==== Post Installation
|
51
32
|
|
@@ -54,20 +35,11 @@ To use it, add it to your Gemfile:
|
|
54
35
|
|
55
36
|
== Testing
|
56
37
|
|
57
|
-
Acts As Taggable On uses RSpec for its test coverage. Inside the
|
58
|
-
directory, you can run the specs for RoR 3.
|
38
|
+
Acts As Taggable On uses RSpec for its test coverage. Inside the gem
|
39
|
+
directory, you can run the specs for RoR 3.x with:
|
59
40
|
|
60
41
|
rake spec
|
61
42
|
|
62
|
-
If you want to test the plugin for Rails 2.3.x, use:
|
63
|
-
|
64
|
-
rake rails2.3:spec
|
65
|
-
|
66
|
-
If you already have RSpec on your application, the specs will run while using:
|
67
|
-
|
68
|
-
rake spec:plugins
|
69
|
-
|
70
|
-
|
71
43
|
== Usage
|
72
44
|
|
73
45
|
class User < ActiveRecord::Base
|
@@ -96,8 +68,8 @@ This way you can mix and match to filter down your results, and it also improves
|
|
96
68
|
compatibility with the will_paginate gem:
|
97
69
|
|
98
70
|
class User < ActiveRecord::Base
|
99
|
-
acts_as_taggable_on :tags
|
100
|
-
|
71
|
+
acts_as_taggable_on :tags, :skills
|
72
|
+
scope :by_join_date, order("created_at DESC")
|
101
73
|
end
|
102
74
|
|
103
75
|
User.tagged_with("awesome").by_date
|
@@ -105,14 +77,24 @@ compatibility with the will_paginate gem:
|
|
105
77
|
|
106
78
|
# Find a user with matching all tags, not just one
|
107
79
|
User.tagged_with(["awesome", "cool"], :match_all => :true)
|
108
|
-
|
80
|
+
|
109
81
|
# Find a user with any of the tags:
|
110
82
|
User.tagged_with(["awesome", "cool"], :any => true)
|
111
83
|
|
84
|
+
# Find a user that not tags with awesome or cool:
|
85
|
+
User.tagged_with(["awesome", "cool"], :exclude => true)
|
86
|
+
|
87
|
+
# Find a user with any of tags based on context:
|
88
|
+
User.tagged_with(['awesome, cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
|
89
|
+
|
90
|
+
You can also use :wild => true option along with :any or :exclude option. It will looking for %awesome% and %cool% in sql.
|
91
|
+
|
92
|
+
Tip: User.tagged_with([]) or '' will return [], but not all records.
|
93
|
+
|
112
94
|
=== Relationships
|
113
95
|
|
114
96
|
You can find objects of the same type based on similar tags on certain contexts.
|
115
|
-
Also, objects will be returned in descending order based on the total number of
|
97
|
+
Also, objects will be returned in descending order based on the total number of
|
116
98
|
matched tags.
|
117
99
|
|
118
100
|
@bobby = User.find_by_name("Bobby")
|
@@ -125,8 +107,8 @@ matched tags.
|
|
125
107
|
@tom.skill_list # => ["hacking", "jogging", "diving"]
|
126
108
|
|
127
109
|
@tom.find_related_skills # => [<User name="Bobby">,<User name="Frankie">]
|
128
|
-
@bobby.find_related_skills # => [<User name="Tom">]
|
129
|
-
@frankie.find_related_skills # => [<User name="Tom">]
|
110
|
+
@bobby.find_related_skills # => [<User name="Tom">]
|
111
|
+
@frankie.find_related_skills # => [<User name="Tom">]
|
130
112
|
|
131
113
|
=== Dynamic Tag Contexts
|
132
114
|
|
@@ -156,8 +138,10 @@ Tags can have owners:
|
|
156
138
|
@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations)
|
157
139
|
@some_user.owned_taggings
|
158
140
|
@some_user.owned_tags
|
159
|
-
@some_photo.locations_from(@some_user)
|
160
|
-
|
141
|
+
@some_photo.locations_from(@some_user) # => ["paris", "normandy"]
|
142
|
+
@some_photo.owner_tags_on(@some_user, :locations) # => [#<ActsAsTaggableOn::Tag id: 1, name: "paris">...]
|
143
|
+
@some_photo.owner_tags_on(nil, :locations) # => Ownerships equivalent to saying @some_photo.locations
|
144
|
+
|
161
145
|
=== Tag cloud calculations
|
162
146
|
|
163
147
|
To construct tag clouds, the frequency of each tag needs to be calculated.
|
@@ -198,24 +182,24 @@ CSS:
|
|
198
182
|
.css3 { font-size: 1.4em; }
|
199
183
|
.css4 { font-size: 1.6em; }
|
200
184
|
|
185
|
+
== Remove unused tags
|
186
|
+
|
187
|
+
If you would like to remove unused tag objects after removing taggings, add
|
188
|
+
|
189
|
+
ActsAsTaggableOn::Tag.remove_unused = true
|
190
|
+
|
191
|
+
to initializer file.
|
192
|
+
|
201
193
|
== Contributors
|
202
194
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
*
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
* azabaj - Fixed migrate down
|
215
|
-
* Peter Cooper - named_scope fix
|
216
|
-
* slainer68 - STI fix
|
217
|
-
* harrylove - migration instructions and fix-ups
|
218
|
-
* lawrencepit - cached tag work
|
219
|
-
* sobrinho - fixed tag_cloud helper
|
220
|
-
|
221
|
-
Copyright (c) 2007-2010 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
|
195
|
+
We have a long list of valued contributors. {Check them all}[https://github.com/mbleigh/acts-as-taggable-on/contributors]
|
196
|
+
|
197
|
+
== Maintainers
|
198
|
+
|
199
|
+
* Artem Kramarenko (artemk)
|
200
|
+
|
201
|
+
== Author
|
202
|
+
|
203
|
+
* Michael Bleigh
|
204
|
+
|
205
|
+
Copyright (c) 2007-2011 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,59 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
Bundler.setup :default, :development
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
Spec::Rake::SpecTask.new do |t|
|
8
|
-
t.spec_files = FileList["spec/**/*_spec.rb"]
|
9
|
-
end
|
5
|
+
desc 'Default: run specs'
|
6
|
+
task :default => :spec
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
t.rcov_opts = ['--exclude', 'spec']
|
15
|
-
end
|
16
|
-
|
17
|
-
rescue LoadError
|
18
|
-
# Rspec 2.0
|
19
|
-
require 'rspec/core/rake_task'
|
20
|
-
|
21
|
-
desc 'Default: run specs'
|
22
|
-
task :default => :spec
|
23
|
-
Rspec::Core::RakeTask.new do |t|
|
24
|
-
t.pattern = "spec/**/*_spec.rb"
|
25
|
-
end
|
26
|
-
|
27
|
-
Rspec::Core::RakeTask.new('rcov') do |t|
|
28
|
-
t.pattern = "spec/**/*_spec.rb"
|
29
|
-
t.rcov = true
|
30
|
-
t.rcov_opts = ['--exclude', 'spec']
|
31
|
-
end
|
32
|
-
|
33
|
-
rescue LoadError
|
34
|
-
puts "Rspec not available. Install it with: gem install rspec"
|
35
|
-
end
|
36
|
-
|
37
|
-
namespace 'rails2.3' do
|
38
|
-
task :spec do
|
39
|
-
gemfile = File.join(File.dirname(__FILE__), 'lib', 'acts_as_taggable_on', 'compatibility', 'Gemfile')
|
40
|
-
ENV['BUNDLE_GEMFILE'] = gemfile
|
41
|
-
Rake::Task['spec'].invoke
|
42
|
-
end
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.pattern = "spec/**/*_spec.rb"
|
43
11
|
end
|
44
12
|
|
45
|
-
|
46
|
-
require 'jeweler'
|
47
|
-
Jeweler::Tasks.new do |gemspec|
|
48
|
-
gemspec.name = "acts-as-taggable-on"
|
49
|
-
gemspec.summary = "ActsAsTaggableOn is a tagging plugin for Rails that provides multiple tagging contexts on a single model."
|
50
|
-
gemspec.description = "With ActsAsTaggableOn, you could tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality."
|
51
|
-
gemspec.email = "michael@intridea.com"
|
52
|
-
gemspec.homepage = "http://github.com/mbleigh/acts-as-taggable-on"
|
53
|
-
gemspec.authors = ["Michael Bleigh"]
|
54
|
-
gemspec.files = FileList["[A-Z]*", "{generators,lib,spec,rails}/**/*"] - FileList["**/*.log"]
|
55
|
-
end
|
56
|
-
Jeweler::GemcutterTasks.new
|
57
|
-
rescue LoadError
|
58
|
-
puts "Jeweler not available. Install it with: gem install jeweler"
|
59
|
-
end
|
13
|
+
Bundler::GemHelper.install_tasks
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.push File.dirname(__FILE__) + '/lib'
|
2
|
+
require 'acts-as-taggable-on/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = %q{acts-as-taggable-on}
|
6
|
+
gem.authors = ["Michael Bleigh"]
|
7
|
+
gem.date = %q{2012-01-06}
|
8
|
+
gem.description = %q{With ActsAsTaggableOn, you can tag a single model on several contexts, such as skills, interests, and awards. It also provides other advanced functionality.}
|
9
|
+
gem.summary = "Advanced tagging for Rails."
|
10
|
+
gem.email = %q{michael@intridea.com}
|
11
|
+
gem.homepage = ''
|
12
|
+
|
13
|
+
gem.add_runtime_dependency 'rails', '~> 3.0'
|
14
|
+
gem.add_development_dependency 'rspec', '~> 2.5'
|
15
|
+
gem.add_development_dependency 'ammeter', '~> 0.1.3'
|
16
|
+
gem.add_development_dependency 'sqlite3'
|
17
|
+
gem.add_development_dependency 'mysql2', '~> 0.3.7'
|
18
|
+
gem.add_development_dependency 'pg'
|
19
|
+
gem.add_development_dependency 'guard'
|
20
|
+
gem.add_development_dependency 'guard-rspec'
|
21
|
+
|
22
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
gem.files = `git ls-files`.split("\n")
|
24
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
gem.name = "acts-as-taggable-on"
|
26
|
+
gem.require_paths = ['lib']
|
27
|
+
gem.version = ActsAsTaggableOn::VERSION
|
28
|
+
end
|
data/lib/acts-as-taggable-on.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
require "active_record"
|
2
|
+
require "active_record/version"
|
2
3
|
require "action_view"
|
3
4
|
|
5
|
+
require "digest/sha1"
|
6
|
+
|
4
7
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
8
|
|
6
|
-
require "acts_as_taggable_on/
|
9
|
+
require "acts_as_taggable_on/utils"
|
7
10
|
|
8
|
-
require "acts_as_taggable_on/
|
11
|
+
require "acts_as_taggable_on/taggable"
|
9
12
|
require "acts_as_taggable_on/acts_as_taggable_on/core"
|
10
13
|
require "acts_as_taggable_on/acts_as_taggable_on/collection"
|
11
14
|
require "acts_as_taggable_on/acts_as_taggable_on/cache"
|
12
15
|
require "acts_as_taggable_on/acts_as_taggable_on/ownership"
|
13
16
|
require "acts_as_taggable_on/acts_as_taggable_on/related"
|
14
17
|
|
15
|
-
require "acts_as_taggable_on/
|
18
|
+
require "acts_as_taggable_on/tagger"
|
16
19
|
require "acts_as_taggable_on/tag"
|
17
20
|
require "acts_as_taggable_on/tag_list"
|
18
21
|
require "acts_as_taggable_on/tags_helper"
|
@@ -20,6 +23,7 @@ require "acts_as_taggable_on/tagging"
|
|
20
23
|
|
21
24
|
$LOAD_PATH.shift
|
22
25
|
|
26
|
+
|
23
27
|
if defined?(ActiveRecord::Base)
|
24
28
|
ActiveRecord::Base.extend ActsAsTaggableOn::Taggable
|
25
29
|
ActiveRecord::Base.send :include, ActsAsTaggableOn::Tagger
|
@@ -11,11 +11,11 @@ module ActsAsTaggableOn::Taggable
|
|
11
11
|
before_save :save_cached_tag_list
|
12
12
|
end
|
13
13
|
|
14
|
-
base.
|
14
|
+
base.initialize_acts_as_taggable_on_cache
|
15
15
|
end
|
16
16
|
|
17
17
|
module ClassMethods
|
18
|
-
def
|
18
|
+
def initialize_acts_as_taggable_on_cache
|
19
19
|
tag_types.map(&:to_s).each do |tag_type|
|
20
20
|
class_eval %(
|
21
21
|
def self.caching_#{tag_type.singularize}_list?
|
@@ -27,7 +27,7 @@ module ActsAsTaggableOn::Taggable
|
|
27
27
|
|
28
28
|
def acts_as_taggable_on(*args)
|
29
29
|
super(*args)
|
30
|
-
|
30
|
+
initialize_acts_as_taggable_on_cache
|
31
31
|
end
|
32
32
|
|
33
33
|
def caching_tag_list_on?(context)
|
@@ -40,7 +40,7 @@ module ActsAsTaggableOn::Taggable
|
|
40
40
|
tag_types.map(&:to_s).each do |tag_type|
|
41
41
|
if self.class.send("caching_#{tag_type.singularize}_list?")
|
42
42
|
if tag_list_cache_set_on(tag_type)
|
43
|
-
list = tag_list_cache_on(tag_type
|
43
|
+
list = tag_list_cache_on(tag_type).to_a.flatten.compact.join(', ')
|
44
44
|
self["cached_#{tag_type.singularize}_list"] = list
|
45
45
|
end
|
46
46
|
end
|
@@ -53,73 +53,68 @@ module ActsAsTaggableOn::Taggable
|
|
53
53
|
def all_tag_counts(options = {})
|
54
54
|
options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :on, :id
|
55
55
|
|
56
|
-
scope =
|
57
|
-
{}
|
58
|
-
else
|
59
|
-
scope(:find) || {}
|
60
|
-
end
|
56
|
+
scope = {}
|
61
57
|
|
62
58
|
## Generate conditions:
|
63
59
|
options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
|
64
|
-
|
60
|
+
|
65
61
|
start_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
|
66
62
|
end_at_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
|
67
|
-
|
63
|
+
|
68
64
|
taggable_conditions = sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.taggable_type = ?", base_class.name])
|
69
|
-
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = ?", options.delete(:id)])
|
70
|
-
|
71
|
-
|
65
|
+
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = ?", options.delete(:id)]) if options[:id]
|
66
|
+
taggable_conditions << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on]
|
67
|
+
|
68
|
+
tagging_conditions = [
|
72
69
|
taggable_conditions,
|
73
|
-
options[:conditions],
|
74
70
|
scope[:conditions],
|
75
71
|
start_at_conditions,
|
76
72
|
end_at_conditions
|
77
73
|
].compact.reverse
|
78
74
|
|
75
|
+
tag_conditions = [
|
76
|
+
options[:conditions]
|
77
|
+
].compact.reverse
|
78
|
+
|
79
79
|
## Generate joins:
|
80
|
-
tagging_join = "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tag.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.tag_id"
|
81
|
-
tagging_join << sanitize_sql([" AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on]
|
82
|
-
|
83
80
|
taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id"
|
84
81
|
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
|
85
82
|
|
86
|
-
|
87
|
-
tagging_join,
|
83
|
+
tagging_joins = [
|
88
84
|
taggable_join,
|
89
85
|
scope[:joins]
|
90
86
|
].compact
|
91
87
|
|
92
|
-
|
93
|
-
|
88
|
+
tag_joins = [
|
89
|
+
].compact
|
94
90
|
|
95
91
|
## Generate scope:
|
96
|
-
|
97
|
-
|
92
|
+
tagging_scope = ActsAsTaggableOn::Tagging.select("#{ActsAsTaggableOn::Tagging.table_name}.tag_id, COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) AS tags_count")
|
93
|
+
tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*, #{ActsAsTaggableOn::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit])
|
94
|
+
|
98
95
|
# Joins and conditions
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
tagging_joins.each { |join| tagging_scope = tagging_scope.joins(join) }
|
97
|
+
tagging_conditions.each { |condition| tagging_scope = tagging_scope.where(condition) }
|
98
|
+
|
99
|
+
tag_joins.each { |join| tag_scope = tag_scope.joins(join) }
|
100
|
+
tag_conditions.each { |condition| tag_scope = tag_scope.where(condition) }
|
101
|
+
|
102
102
|
# GROUP BY and HAVING clauses:
|
103
|
-
at_least = sanitize_sql(['
|
104
|
-
at_most = sanitize_sql(['
|
105
|
-
having = [at_least, at_most].compact.join(' AND ')
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
group_by << " AND #{having}" unless having.blank?
|
119
|
-
scope = scope.group(group_by)
|
120
|
-
end
|
121
|
-
|
122
|
-
scope
|
103
|
+
at_least = sanitize_sql(['tags_count >= ?', options.delete(:at_least)]) if options[:at_least]
|
104
|
+
at_most = sanitize_sql(['tags_count <= ?', options.delete(:at_most)]) if options[:at_most]
|
105
|
+
having = ["COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) > 0", at_least, at_most].compact.join(' AND ')
|
106
|
+
|
107
|
+
group_columns = "#{ActsAsTaggableOn::Tagging.table_name}.tag_id"
|
108
|
+
|
109
|
+
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
|
110
|
+
scoped_select = "#{table_name}.#{primary_key}"
|
111
|
+
tagging_scope = tagging_scope.where("#{ActsAsTaggableOn::Tagging.table_name}.taggable_id IN(#{select(scoped_select).to_sql})").
|
112
|
+
group(group_columns).
|
113
|
+
having(having)
|
114
|
+
|
115
|
+
|
116
|
+
tag_scope = tag_scope.joins("JOIN (#{tagging_scope.to_sql}) AS #{ActsAsTaggableOn::Tagging.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id")
|
117
|
+
tag_scope
|
123
118
|
end
|
124
119
|
end
|
125
120
|
|