acts-as-taggable-on 2.0.6 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|