acts-as-taggable-on 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +1 -2
  3. data/README.rdoc +27 -50
  4. data/acts-as-taggable-on.gemspec +4 -3
  5. data/lib/acts-as-taggable-on.rb +0 -4
  6. data/lib/acts-as-taggable-on/version.rb +1 -1
  7. data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +4 -13
  8. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +1 -1
  9. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +1 -1
  10. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +29 -17
  11. data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +15 -15
  12. data/lib/acts_as_taggable_on/tag.rb +12 -13
  13. data/lib/acts_as_taggable_on/tagging.rb +0 -2
  14. data/lib/acts_as_taggable_on/utils.rb +7 -8
  15. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +228 -61
  16. data/spec/acts_as_taggable_on/tag_list_spec.rb +4 -0
  17. data/spec/acts_as_taggable_on/tag_spec.rb +11 -15
  18. data/spec/acts_as_taggable_on/taggable_spec.rb +89 -27
  19. data/spec/acts_as_taggable_on/tagger_spec.rb +14 -0
  20. data/spec/acts_as_taggable_on/utils_spec.rb +2 -3
  21. data/spec/database.yml.sample +1 -1
  22. data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +22 -0
  23. data/spec/models.rb +11 -2
  24. data/spec/schema.rb +7 -0
  25. data/spec/spec_helper.rb +1 -0
  26. metadata +95 -122
  27. data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
  28. data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
  29. data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -8
  30. data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -21
data/.gitignore CHANGED
@@ -5,3 +5,4 @@
5
5
  .rvmrc
6
6
  Gemfile.lock
7
7
  spec/database.yml
8
+ tmp
@@ -1,9 +1,8 @@
1
1
  script: "cp spec/database.yml.sample spec/database.yml && bundle install && bundle exec rake"
2
2
  rvm:
3
3
  - 1.8.7
4
- - ree
5
4
  - 1.9.2
6
- - rbx
5
+ - 1.9.3
7
6
  env:
8
7
  - DB=sqlite3
9
8
  - DB=mysql
@@ -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,34 +18,15 @@ was used.
17
18
 
18
19
  === Rails 2.3.x
19
20
 
20
- The last version of gem that is compatible with Rails 2.3.x is 2.1.0.
21
-
22
- We are planning no longer to support Rails 2, but if you want to contribute something only for Rails 2, we left rails2 branch for that.
23
-
24
- ==== Plugin
25
-
26
- Acts As Taggable On is available both as a gem and as a traditional plugin. For the
27
- traditional plugin you can install like so:
28
-
29
- script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git
30
-
31
- Acts As Taggable On is also available as a gem plugin using Rails 2.1's gem dependencies.
32
- To install the gem, add this to your config/environment.rb:
33
-
34
- config.gem "acts-as-taggable-on", :source => "http://gemcutter.org", :version => '2.1.0'
35
-
36
- After that, you can run "rake gems:install" to install the gem if you don't already have it.
21
+ To use it, add it to your Gemfile:
37
22
 
38
- ==== Post Installation
39
-
40
- 1. script/generate acts_as_taggable_on_migration
41
- 2. rake db:migrate
23
+ gem 'acts-as-taggable-on', '2.1.0'
42
24
 
43
25
  === Rails 3.x
44
26
 
45
27
  To use it, add it to your Gemfile:
46
-
47
- gem 'acts-as-taggable-on', '~>2.1.0'
28
+
29
+ gem 'acts-as-taggable-on'
48
30
 
49
31
  ==== Post Installation
50
32
 
@@ -87,7 +69,7 @@ compatibility with the will_paginate gem:
87
69
 
88
70
  class User < ActiveRecord::Base
89
71
  acts_as_taggable_on :tags, :skills
90
- named_scope :by_join_date, :order => "created_at DESC"
72
+ scope :by_join_date, order("created_at DESC")
91
73
  end
92
74
 
93
75
  User.tagged_with("awesome").by_date
@@ -95,17 +77,19 @@ compatibility with the will_paginate gem:
95
77
 
96
78
  # Find a user with matching all tags, not just one
97
79
  User.tagged_with(["awesome", "cool"], :match_all => :true)
98
-
80
+
99
81
  # Find a user with any of the tags:
100
82
  User.tagged_with(["awesome", "cool"], :any => true)
101
-
83
+
102
84
  # Find a user with any of tags based on context:
103
85
  User.tagged_with(['awesome, cool'], :on => :tags, :any => true).tagged_with(['smart', 'shy'], :on => :skills, :any => true)
104
-
86
+
87
+ Note: User.tagged_with([]) or '' will return [], but not all records.
88
+
105
89
  === Relationships
106
90
 
107
91
  You can find objects of the same type based on similar tags on certain contexts.
108
- Also, objects will be returned in descending order based on the total number of
92
+ Also, objects will be returned in descending order based on the total number of
109
93
  matched tags.
110
94
 
111
95
  @bobby = User.find_by_name("Bobby")
@@ -118,8 +102,8 @@ matched tags.
118
102
  @tom.skill_list # => ["hacking", "jogging", "diving"]
119
103
 
120
104
  @tom.find_related_skills # => [<User name="Bobby">,<User name="Frankie">]
121
- @bobby.find_related_skills # => [<User name="Tom">]
122
- @frankie.find_related_skills # => [<User name="Tom">]
105
+ @bobby.find_related_skills # => [<User name="Tom">]
106
+ @frankie.find_related_skills # => [<User name="Tom">]
123
107
 
124
108
  === Dynamic Tag Contexts
125
109
 
@@ -149,8 +133,10 @@ Tags can have owners:
149
133
  @some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations)
150
134
  @some_user.owned_taggings
151
135
  @some_user.owned_tags
152
- @some_photo.locations_from(@some_user)
153
-
136
+ @some_photo.locations_from(@some_user) # => ["paris", "normandy"]
137
+ @some_photo.owner_tags_on(@some_user, :locations) # => [#<ActsAsTaggableOn::Tag id: 1, name: "paris">...]
138
+ @some_photo.owner_tags_on(nil, :locations) # => Ownerships equivalent to saying @some_photo.locations
139
+
154
140
  === Tag cloud calculations
155
141
 
156
142
  To construct tag clouds, the frequency of each tag needs to be calculated.
@@ -193,23 +179,14 @@ CSS:
193
179
 
194
180
  == Contributors
195
181
 
196
- * Artem Kramarenko (artemk) - Maintainer
197
- * TomEric (i76) - Maintainer
198
- * Michael Bleigh - Original Author
199
- * Szymon Nowak - Rails 3.0 compatibility
200
- * Jelle Vandebeeck - Rails 3.0 compatibility
201
- * Brendan Lim - Related Objects
202
- * Pradeep Elankumaran - Taggers
203
- * Sinclair Bain - Patch King
204
-
205
- === Patch Contributors
206
-
207
- * tristanzdunn - Related objects of other classes
208
- * azabaj - Fixed migrate down
209
- * Peter Cooper - named_scope fix
210
- * slainer68 - STI fix
211
- * harrylove - migration instructions and fix-ups
212
- * lawrencepit - cached tag work
213
- * sobrinho - fixed tag_cloud helper
182
+ We have a long list of valued contributors. {Check them all}[https://github.com/mbleigh/acts-as-taggable-on/contributors]
183
+
184
+ == Maintainers
185
+
186
+ * Artem Kramarenko (artemk)
187
+
188
+ == Author
189
+
190
+ * Michael Bleigh
214
191
 
215
192
  Copyright (c) 2007-2011 Michael Bleigh (http://mbleigh.com/) and Intridea Inc. (http://intridea.com/), released under the MIT license
@@ -4,16 +4,17 @@ require 'acts-as-taggable-on/version'
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = %q{acts-as-taggable-on}
6
6
  gem.authors = ["Michael Bleigh"]
7
- gem.date = %q{2010-05-19}
7
+ gem.date = %q{2011-12-09}
8
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
9
  gem.summary = "Advanced tagging for Rails."
10
10
  gem.email = %q{michael@intridea.com}
11
11
  gem.homepage = ''
12
12
 
13
- gem.add_runtime_dependency 'rails'
13
+ gem.add_runtime_dependency 'rails', '~> 3.1'
14
14
  gem.add_development_dependency 'rspec', '~> 2.5'
15
+ gem.add_development_dependency 'ammeter', '~> 0.1.3'
15
16
  gem.add_development_dependency 'sqlite3'
16
- gem.add_development_dependency 'mysql2', '< 0.3'
17
+ gem.add_development_dependency 'mysql2', '~> 0.3.7'
17
18
  gem.add_development_dependency 'pg'
18
19
  gem.add_development_dependency 'guard'
19
20
  gem.add_development_dependency 'guard-rspec'
@@ -1,12 +1,9 @@
1
1
  require "active_record"
2
2
  require "active_record/version"
3
3
  require "action_view"
4
- RAILS_3 = ::ActiveRecord::VERSION::MAJOR >= 3
5
4
 
6
5
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
6
 
8
- require "acts_as_taggable_on/compatibility/active_record_backports" unless RAILS_3
9
-
10
7
  require "acts_as_taggable_on/utils"
11
8
 
12
9
  require "acts_as_taggable_on/acts_as_taggable_on"
@@ -16,7 +13,6 @@ require "acts_as_taggable_on/acts_as_taggable_on/cache"
16
13
  require "acts_as_taggable_on/acts_as_taggable_on/ownership"
17
14
  require "acts_as_taggable_on/acts_as_taggable_on/related"
18
15
 
19
- #require "acts_as_taggable_on/utils"
20
16
  require "acts_as_taggable_on/acts_as_tagger"
21
17
  require "acts_as_taggable_on/tag"
22
18
  require "acts_as_taggable_on/tag_list"
@@ -1,4 +1,4 @@
1
1
  module ActsAsTaggableOn
2
- VERSION = '2.1.1'
2
+ VERSION = '2.2.0'
3
3
  end
4
4
 
@@ -28,20 +28,11 @@ module ActsAsTaggableOn
28
28
  tag_types = tag_types.to_a.flatten.compact.map(&:to_sym)
29
29
 
30
30
  if taggable?
31
- if RAILS_3
32
- self.tag_types = (self.tag_types + tag_types).uniq
33
- else
34
- write_inheritable_attribute(:tag_types, (self.tag_types + tag_types).uniq)
35
- end
31
+ self.tag_types = (self.tag_types + tag_types).uniq
36
32
  else
37
- if RAILS_3
38
33
  class_attribute :tag_types
39
34
  self.tag_types = tag_types
40
- else
41
- write_inheritable_attribute(:tag_types, tag_types)
42
- class_inheritable_reader(:tag_types)
43
- end
44
-
35
+
45
36
  class_eval do
46
37
  has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging"
47
38
  has_many :base_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag"
@@ -49,8 +40,8 @@ module ActsAsTaggableOn
49
40
  def self.taggable?
50
41
  true
51
42
  end
52
-
53
- include ActsAsTaggableOn::Utils
43
+
44
+ include ActsAsTaggableOn::Utils
54
45
  include ActsAsTaggableOn::Taggable::Core
55
46
  include ActsAsTaggableOn::Taggable::Collection
56
47
  include ActsAsTaggableOn::Taggable::Cache
@@ -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.singularize).to_a.flatten.compact.join(', ')
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
@@ -125,7 +125,7 @@ module ActsAsTaggableOn::Taggable
125
125
  tagging_scope = tagging_scope.group(group_by)
126
126
  end
127
127
 
128
- tag_scope = tag_scope.joins("JOIN (#{tagging_scope.to_sql}) AS taggings ON taggings.tag_id = tags.id")
128
+ 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")
129
129
  tag_scope
130
130
  end
131
131
  end
@@ -1,5 +1,5 @@
1
1
  module ActsAsTaggableOn::Taggable
2
- module Core
2
+ module Core
3
3
  def self.included(base)
4
4
  base.send :include, ActsAsTaggableOn::Taggable::Core::InstanceMethods
5
5
  base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
@@ -8,10 +8,10 @@ module ActsAsTaggableOn::Taggable
8
8
  attr_writer :custom_contexts
9
9
  after_save :save_tags
10
10
  end
11
-
11
+
12
12
  base.initialize_acts_as_taggable_on_core
13
13
  end
14
-
14
+
15
15
  module ClassMethods
16
16
  def initialize_acts_as_taggable_on_core
17
17
  tag_types.map(&:to_s).each do |tags_type|
@@ -20,9 +20,9 @@ module ActsAsTaggableOn::Taggable
20
20
  context_tags = tags_type.to_sym
21
21
 
22
22
  class_eval do
23
- has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging",
24
- :conditions => ["#{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_type]
25
- has_many context_tags, :through => context_taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag"
23
+ has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "ActsAsTaggableOn::Tagging",
24
+ :conditions => ["#{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_type]
25
+ has_many context_tags, :through => context_taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag"
26
26
  end
27
27
 
28
28
  class_eval %(
@@ -38,14 +38,14 @@ module ActsAsTaggableOn::Taggable
38
38
  all_tags_list_on('#{tags_type}')
39
39
  end
40
40
  )
41
- end
41
+ end
42
42
  end
43
-
43
+
44
44
  def acts_as_taggable_on(*args)
45
45
  super(*args)
46
46
  initialize_acts_as_taggable_on_core
47
47
  end
48
-
48
+
49
49
  # all column names are necessary for PostgreSQL group clause
50
50
  def grouped_column_names_for(object)
51
51
  object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(", ")
@@ -59,12 +59,14 @@ module ActsAsTaggableOn::Taggable
59
59
  # * <tt>:exclude</tt> - if set to true, return objects that are *NOT* tagged with the specified tags
60
60
  # * <tt>:any</tt> - if set to true, return objects that are tagged with *ANY* of the specified tags
61
61
  # * <tt>:match_all</tt> - if set to true, return objects that are *ONLY* tagged with the specified tags
62
+ # * <tt>:owned_by</tt> - return objects that are *ONLY* owned by the owner
62
63
  #
63
64
  # Example:
64
65
  # User.tagged_with("awesome", "cool") # Users that are tagged with awesome and cool
65
66
  # User.tagged_with("awesome", "cool", :exclude => true) # Users that are not tagged with awesome or cool
66
67
  # User.tagged_with("awesome", "cool", :any => true) # Users that are tagged with awesome or cool
67
68
  # User.tagged_with("awesome", "cool", :match_all => true) # Users that are tagged with just awesome and cool
69
+ # User.tagged_with("awesome", "cool", :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo'
68
70
  def tagged_with(tags, options = {})
69
71
  tag_list = ActsAsTaggableOn::TagList.from(tags)
70
72
  empty_result = scoped(:conditions => "1 = 0")
@@ -75,11 +77,12 @@ module ActsAsTaggableOn::Taggable
75
77
  conditions = []
76
78
 
77
79
  context = options.delete(:on)
80
+ owned_by = options.delete(:owned_by)
78
81
  alias_base_name = undecorated_table_name.gsub('.','_')
79
82
 
80
83
  if options.delete(:exclude)
81
84
  tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
82
- conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
85
+ conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
83
86
 
84
87
  elsif options.delete(:any)
85
88
  # get tags, drop out if nothing returned (we need at least one)
@@ -89,7 +92,7 @@ module ActsAsTaggableOn::Taggable
89
92
  # setup taggings alias so we can chain, ex: items_locations_taggings_awesome_cool_123
90
93
  # avoid ambiguous column name
91
94
  taggings_context = context ? "_#{context}" : ''
92
-
95
+
93
96
  #TODO: fix alias to be smaller
94
97
  taggings_alias = "#{alias_base_name}#{taggings_context}_taggings_#{tags.map(&:safe_name).join('_')}_#{rand(1024)}"
95
98
 
@@ -119,6 +122,15 @@ module ActsAsTaggableOn::Taggable
119
122
  " AND #{taggings_alias}.tag_id = #{tag.id}"
120
123
  tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
121
124
 
125
+ if owned_by
126
+ tagging_join << " AND " +
127
+ sanitize_sql([
128
+ "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?",
129
+ owned_by.id,
130
+ owned_by.class.to_s
131
+ ])
132
+ end
133
+
122
134
  joins << tagging_join
123
135
  end
124
136
  end
@@ -146,8 +158,8 @@ module ActsAsTaggableOn::Taggable
146
158
  def is_taggable?
147
159
  true
148
160
  end
149
- end
150
-
161
+ end
162
+
151
163
  module InstanceMethods
152
164
  # all column names are necessary for PostgreSQL group clause
153
165
  def grouped_column_names_for(object)
@@ -200,7 +212,7 @@ module ActsAsTaggableOn::Taggable
200
212
 
201
213
  opts = ["#{tagging_table_name}.context = ?", context.to_s]
202
214
  scope = base_tags.where(opts)
203
-
215
+
204
216
  if ActsAsTaggableOn::Tag.using_postgresql?
205
217
  group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
206
218
  scope = scope.order("max(#{tagging_table_name}.created_at)").group(group_columns)
@@ -233,7 +245,7 @@ module ActsAsTaggableOn::Taggable
233
245
  instance_variable_set("@#{context.to_s.singularize}_list", nil)
234
246
  instance_variable_set("@all_#{context.to_s.singularize}_list", nil)
235
247
  end
236
-
248
+
237
249
  super(*args)
238
250
  end
239
251
 
@@ -249,14 +261,14 @@ module ActsAsTaggableOn::Taggable
249
261
  current_tags = tags_on(context)
250
262
  old_tags = current_tags - tag_list
251
263
  new_tags = tag_list - current_tags
252
-
264
+
253
265
  # Find taggings to remove:
254
266
  old_taggings = taggings.where(:tagger_type => nil, :tagger_id => nil,
255
267
  :context => context.to_s, :tag_id => old_tags).all
256
268
 
257
269
  if old_taggings.present?
258
270
  # Destroy old taggings:
259
- ActsAsTaggableOn::Tagging.destroy_all :id => old_taggings.map(&:id)
271
+ ActsAsTaggableOn::Tagging.destroy_all "#{ActsAsTaggableOn::Tagging.primary_key}".to_sym => old_taggings.map(&:id)
260
272
  end
261
273
 
262
274
  # Create new taggings:
@@ -5,7 +5,7 @@ module ActsAsTaggableOn::Taggable
5
5
  base.extend ActsAsTaggableOn::Taggable::Related::ClassMethods
6
6
  base.initialize_acts_as_taggable_on_related
7
7
  end
8
-
8
+
9
9
  module ClassMethods
10
10
  def initialize_acts_as_taggable_on_related
11
11
  tag_types.map(&:to_s).each do |tag_type|
@@ -20,7 +20,7 @@ module ActsAsTaggableOn::Taggable
20
20
  end
21
21
  )
22
22
  end
23
-
23
+
24
24
  unless tag_types.empty?
25
25
  class_eval %(
26
26
  def find_matching_contexts(search_context, result_context, options = {})
@@ -31,43 +31,43 @@ module ActsAsTaggableOn::Taggable
31
31
  matching_contexts_for(search_context.to_s, result_context.to_s, klass, options)
32
32
  end
33
33
  )
34
- end
34
+ end
35
35
  end
36
-
36
+
37
37
  def acts_as_taggable_on(*args)
38
38
  super(*args)
39
39
  initialize_acts_as_taggable_on_related
40
40
  end
41
41
  end
42
-
42
+
43
43
  module InstanceMethods
44
44
  def matching_contexts_for(search_context, result_context, klass, options = {})
45
45
  tags_to_find = tags_on(search_context).collect { |t| t.name }
46
46
 
47
- exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
48
-
47
+ exclude_self = "#{klass.table_name}.#{klass.primary_key} != #{id} AND" if [self.class.base_class, self.class].include? klass
48
+
49
49
  group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
50
-
51
- klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
50
+
51
+ klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count",
52
52
  :from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
53
- :conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?) AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_to_find, result_context],
53
+ :conditions => ["#{exclude_self} #{klass.table_name}.#{klass.primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.base_class.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?) AND #{ActsAsTaggableOn::Tagging.table_name}.context = ?", tags_to_find, result_context],
54
54
  :group => group_columns,
55
55
  :order => "count DESC" }.update(options))
56
56
  end
57
-
57
+
58
58
  def related_tags_for(context, klass, options = {})
59
59
  tags_to_find = tags_on(context).collect { |t| t.name }
60
60
 
61
- exclude_self = "#{klass.table_name}.id != #{id} AND" if self.class == klass
61
+ exclude_self = "#{klass.table_name}.#{klass.primary_key} != #{id} AND" if [self.class.base_class, self.class].include? klass
62
62
 
63
63
  group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(klass) : "#{klass.table_name}.#{klass.primary_key}"
64
64
 
65
- klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.id) AS count",
65
+ klass.scoped({ :select => "#{klass.table_name}.*, COUNT(#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}) AS count",
66
66
  :from => "#{klass.table_name}, #{ActsAsTaggableOn::Tag.table_name}, #{ActsAsTaggableOn::Tagging.table_name}",
67
- :conditions => ["#{exclude_self} #{klass.table_name}.id = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?)", tags_to_find],
67
+ :conditions => ["#{exclude_self} #{klass.table_name}.#{klass.primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = '#{klass.base_class.to_s}' AND #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND #{ActsAsTaggableOn::Tag.table_name}.name IN (?)", tags_to_find],
68
68
  :group => group_columns,
69
69
  :order => "count DESC" }.update(options))
70
70
  end
71
71
  end
72
72
  end
73
- end
73
+ end