acts-as-taggable-on 5.0.0 → 8.1.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.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/spec.yml +95 -0
  3. data/.gitignore +1 -1
  4. data/Appraisals +11 -3
  5. data/CHANGELOG.md +203 -145
  6. data/Gemfile +3 -2
  7. data/README.md +38 -4
  8. data/acts-as-taggable-on.gemspec +2 -6
  9. data/db/migrate/1_acts_as_taggable_on_migration.rb +8 -7
  10. data/db/migrate/2_add_missing_unique_indices.rb +8 -8
  11. data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +3 -3
  12. data/db/migrate/4_add_missing_taggable_index.rb +2 -2
  13. data/db/migrate/5_change_collation_for_tag_names.rb +1 -1
  14. data/db/migrate/6_add_missing_indexes_on_taggings.rb +9 -9
  15. data/db/migrate/7_add_tenant_to_taggings.rb +16 -0
  16. data/gemfiles/activerecord_5.0.gemfile +9 -3
  17. data/gemfiles/activerecord_5.1.gemfile +9 -3
  18. data/gemfiles/activerecord_5.2.gemfile +21 -0
  19. data/gemfiles/activerecord_6.0.gemfile +21 -0
  20. data/gemfiles/{activerecord_4.2.gemfile → activerecord_6.1.gemfile} +10 -2
  21. data/lib/acts-as-taggable-on.rb +6 -2
  22. data/lib/acts_as_taggable_on/tag.rb +16 -19
  23. data/lib/acts_as_taggable_on/taggable.rb +18 -1
  24. data/lib/acts_as_taggable_on/taggable/cache.rb +38 -34
  25. data/lib/acts_as_taggable_on/taggable/collection.rb +9 -7
  26. data/lib/acts_as_taggable_on/taggable/core.rb +39 -22
  27. data/lib/acts_as_taggable_on/taggable/ownership.rb +1 -1
  28. data/lib/acts_as_taggable_on/taggable/related.rb +1 -1
  29. data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +4 -0
  30. data/lib/acts_as_taggable_on/taggable/tagged_with_query/all_tags_query.rb +2 -4
  31. data/lib/acts_as_taggable_on/taggable/tagged_with_query/any_tags_query.rb +2 -7
  32. data/lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb +1 -1
  33. data/lib/acts_as_taggable_on/taggable/tagged_with_query/query_base.rb +5 -5
  34. data/lib/acts_as_taggable_on/tagger.rb +1 -1
  35. data/lib/acts_as_taggable_on/tagging.rb +6 -2
  36. data/lib/acts_as_taggable_on/utils.rb +4 -4
  37. data/lib/acts_as_taggable_on/version.rb +1 -2
  38. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +4 -12
  39. data/spec/acts_as_taggable_on/caching_spec.rb +16 -10
  40. data/spec/acts_as_taggable_on/{taggable/dirty_spec.rb → dirty_spec.rb} +28 -13
  41. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +12 -7
  42. data/spec/acts_as_taggable_on/tag_spec.rb +16 -1
  43. data/spec/acts_as_taggable_on/taggable_spec.rb +21 -14
  44. data/spec/acts_as_taggable_on/tagger_spec.rb +2 -2
  45. data/spec/acts_as_taggable_on/tagging_spec.rb +26 -0
  46. data/spec/internal/app/models/altered_inheriting_taggable_model.rb +2 -0
  47. data/spec/internal/app/models/cached_model_with_array.rb +6 -0
  48. data/spec/internal/app/models/columns_override_model.rb +5 -0
  49. data/spec/internal/app/models/company.rb +1 -1
  50. data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
  51. data/spec/internal/app/models/market.rb +1 -1
  52. data/spec/internal/app/models/non_standard_id_taggable_model.rb +1 -1
  53. data/spec/internal/app/models/student.rb +2 -0
  54. data/spec/internal/app/models/taggable_model.rb +3 -0
  55. data/spec/internal/app/models/user.rb +1 -1
  56. data/spec/internal/config/database.yml.sample +4 -8
  57. data/spec/internal/db/schema.rb +14 -5
  58. data/spec/spec_helper.rb +0 -1
  59. data/spec/support/database.rb +4 -4
  60. metadata +22 -65
  61. data/.travis.yml +0 -29
  62. data/UPGRADING.md +0 -8
  63. data/lib/acts_as_taggable_on/taggable/dirty.rb +0 -36
  64. data/spec/internal/app/models/models.rb +0 -90
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  module ActsAsTaggableOn
3
3
  class Tag < ::ActiveRecord::Base
4
+ self.table_name = ActsAsTaggableOn.tags_table
4
5
 
5
6
  ### ASSOCIATIONS:
6
7
 
@@ -9,7 +10,7 @@ module ActsAsTaggableOn
9
10
  ### VALIDATIONS:
10
11
 
11
12
  validates_presence_of :name
12
- validates_uniqueness_of :name, if: :validates_name_uniqueness?
13
+ validates_uniqueness_of :name, if: :validates_name_uniqueness?, case_sensitive: true
13
14
  validates_length_of :name, maximum: 255
14
15
 
15
16
  # monkey patch this method if don't need name uniqueness validation
@@ -50,8 +51,14 @@ module ActsAsTaggableOn
50
51
 
51
52
  def self.for_context(context)
52
53
  joins(:taggings).
53
- where(["taggings.context = ?", context]).
54
- select("DISTINCT tags.*")
54
+ where(["#{ActsAsTaggableOn.taggings_table}.context = ?", context]).
55
+ select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
56
+ end
57
+
58
+ def self.for_tenant(tenant)
59
+ joins(:taggings).
60
+ where("#{ActsAsTaggableOn.taggings_table}.tenant = ?", tenant.to_s).
61
+ select("DISTINCT #{ActsAsTaggableOn.tags_table}.*")
55
62
  end
56
63
 
57
64
  ### CLASS METHODS:
@@ -69,17 +76,17 @@ module ActsAsTaggableOn
69
76
 
70
77
  return [] if list.empty?
71
78
 
79
+ existing_tags = named_any(list)
72
80
  list.map do |tag_name|
73
81
  begin
74
82
  tries ||= 3
75
-
76
- existing_tags = named_any(list)
77
83
  comparable_tag_name = comparable_name(tag_name)
78
84
  existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
79
85
  existing_tag || create(name: tag_name)
80
86
  rescue ActiveRecord::RecordNotUnique
81
87
  if (tries -= 1).positive?
82
88
  ActiveRecord::Base.connection.execute 'ROLLBACK'
89
+ existing_tags = named_any(list)
83
90
  retry
84
91
  end
85
92
 
@@ -104,8 +111,6 @@ module ActsAsTaggableOn
104
111
 
105
112
  class << self
106
113
 
107
-
108
-
109
114
  private
110
115
 
111
116
  def comparable_name(str)
@@ -120,20 +125,12 @@ module ActsAsTaggableOn
120
125
  ActsAsTaggableOn::Utils.using_mysql? ? 'BINARY ' : nil
121
126
  end
122
127
 
123
- def unicode_downcase(string)
124
- if ActiveSupport::Multibyte::Unicode.respond_to?(:downcase)
125
- ActiveSupport::Multibyte::Unicode.downcase(string)
126
- else
127
- ActiveSupport::Multibyte::Chars.new(string).downcase.to_s
128
- end
128
+ def as_8bit_ascii(string)
129
+ string.to_s.mb_chars
129
130
  end
130
131
 
131
- def as_8bit_ascii(string)
132
- if defined?(Encoding)
133
- string.to_s.dup.force_encoding('BINARY')
134
- else
135
- string.to_s.mb_chars
136
- end
132
+ def unicode_downcase(string)
133
+ as_8bit_ascii(string).downcase
137
134
  end
138
135
 
139
136
  def sanitize_sql_for_named_any(tag)
@@ -54,6 +54,23 @@ module ActsAsTaggableOn
54
54
  taggable_on(true, tag_types)
55
55
  end
56
56
 
57
+ def acts_as_taggable_tenant(tenant)
58
+ if taggable?
59
+ self.tenant_column = tenant
60
+ else
61
+ class_attribute :tenant_column
62
+ self.tenant_column = tenant
63
+ end
64
+
65
+ # each of these add context-specific methods and must be
66
+ # called on each call of taggable_on
67
+ include Core
68
+ include Collection
69
+ include Cache
70
+ include Ownership
71
+ include Related
72
+ end
73
+
57
74
  private
58
75
 
59
76
  # Make a model taggable on specified contexts
@@ -78,6 +95,7 @@ module ActsAsTaggableOn
78
95
  self.tag_types = tag_types
79
96
  class_attribute :preserve_tag_order
80
97
  self.preserve_tag_order = preserve_tag_order
98
+ class_attribute :tenant_column
81
99
 
82
100
  class_eval do
83
101
  has_many :taggings, as: :taggable, dependent: :destroy, class_name: '::ActsAsTaggableOn::Tagging'
@@ -96,7 +114,6 @@ module ActsAsTaggableOn
96
114
  include Cache
97
115
  include Ownership
98
116
  include Related
99
- include Dirty
100
117
  end
101
118
  end
102
119
  end
@@ -3,47 +3,51 @@ module ActsAsTaggableOn::Taggable
3
3
  def self.included(base)
4
4
  # When included, conditionally adds tag caching methods when the model
5
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? do |context|
11
- db_column_names.include?("cached_#{context.to_s.singularize}_list")
12
- end
6
+ base.extend Columns
7
+ end
8
+
9
+ module Columns
10
+ # ActiveRecord::Base.columns makes a database connection and caches the
11
+ # calculated columns hash for the record as @columns. Since we don't
12
+ # want to add caching methods until we confirm the presence of a
13
+ # caching column, and we don't want to force opening a database
14
+ # connection when the class is loaded, here we intercept and cache
15
+ # the call to :columns as @acts_as_taggable_on_cache_columns
16
+ # to mimic the underlying behavior. While processing this first
17
+ # call to columns, we do the caching column check and dynamically add
18
+ # the class and instance methods
19
+ # FIXME: this method cannot compile in rubinius
20
+ def columns
21
+ @acts_as_taggable_on_cache_columns ||= begin
22
+ db_columns = super
23
+ _add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
24
+ db_columns
13
25
  end
26
+ end
14
27
 
15
- # @private
16
- def _add_tags_caching_methods
17
- send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
18
- extend ActsAsTaggableOn::Taggable::Cache::ClassMethods
28
+ def reset_column_information
29
+ super
30
+ @acts_as_taggable_on_cache_columns = nil
31
+ end
19
32
 
20
- before_save :save_cached_tag_list
33
+ private
21
34
 
22
- initialize_tags_cache
35
+ # @private
36
+ def _has_tags_cache_columns?(db_columns)
37
+ db_column_names = db_columns.map(&:name)
38
+ tag_types.any? do |context|
39
+ db_column_names.include?("cached_#{context.to_s.singularize}_list")
23
40
  end
41
+ end
24
42
 
25
- # ActiveRecord::Base.columns makes a database connection and caches the
26
- # calculated columns hash for the record as @columns. Since we don't
27
- # want to add caching methods until we confirm the presence of a
28
- # caching column, and we don't want to force opening a database
29
- # connection when the class is loaded, here we intercept and cache
30
- # the call to :columns as @acts_as_taggable_on_cache_columns
31
- # to mimic the underlying behavior. While processing this first
32
- # call to columns, we do the caching column check and dynamically add
33
- # the class and instance methods
34
- # FIXME: this method cannot compile in rubinius
35
- def columns
36
- @acts_as_taggable_on_cache_columns ||= begin
37
- db_columns = super
38
- _add_tags_caching_methods if _has_tags_cache_columns?(db_columns)
39
- db_columns
40
- end
41
- end
43
+ # @private
44
+ def _add_tags_caching_methods
45
+ send :include, ActsAsTaggableOn::Taggable::Cache::InstanceMethods
46
+ extend ActsAsTaggableOn::Taggable::Cache::ClassMethods
42
47
 
43
- def reset_column_information
44
- super
45
- @acts_as_taggable_on_cache_columns = nil
46
- end
48
+ before_save :save_cached_tag_list
49
+
50
+ initialize_tags_cache
47
51
  end
48
52
  end
49
53
 
@@ -94,16 +94,18 @@ module ActsAsTaggableOn::Taggable
94
94
  ## Generate conditions:
95
95
  options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
96
96
 
97
- ## Generate joins:
98
- taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id"
99
- 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
100
-
101
97
  ## Generate scope:
102
98
  tagging_scope = ActsAsTaggableOn::Tagging.select("#{ActsAsTaggableOn::Tagging.table_name}.tag_id, COUNT(#{ActsAsTaggableOn::Tagging.table_name}.tag_id) AS tags_count")
103
99
  tag_scope = ActsAsTaggableOn::Tag.select("#{ActsAsTaggableOn::Tag.table_name}.*, #{ActsAsTaggableOn::Tagging.table_name}.tags_count AS count").order(options[:order]).limit(options[:limit])
104
100
 
105
- # Joins and conditions
106
- tagging_scope = tagging_scope.joins(taggable_join)
101
+ # Current model is STI descendant, so add type checking to the join condition
102
+ unless descends_from_active_record?
103
+ taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{ActsAsTaggableOn::Tagging.table_name}.taggable_id"
104
+ taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'"
105
+ tagging_scope = tagging_scope.joins(taggable_join)
106
+ end
107
+
108
+ # Conditions
107
109
  tagging_conditions(options).each { |condition| tagging_scope = tagging_scope.where(condition) }
108
110
  tag_scope = tag_scope.where(options[:conditions])
109
111
 
@@ -174,7 +176,7 @@ module ActsAsTaggableOn::Taggable
174
176
  # See https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb#L38
175
177
  def count(column_name = :all, options = {})
176
178
  # https://github.com/rails/rails/commit/da9b5d4a8435b744fcf278fffd6d7f1e36d4a4f2
177
- ActsAsTaggableOn::Utils.active_record5? ? super(column_name) : super(column_name, options)
179
+ super(column_name)
178
180
  end
179
181
  end
180
182
  end
@@ -1,7 +1,9 @@
1
1
  require_relative 'tagged_with_query'
2
+ require_relative 'tag_list_type'
2
3
 
3
4
  module ActsAsTaggableOn::Taggable
4
5
  module Core
6
+
5
7
  def self.included(base)
6
8
  base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
7
9
 
@@ -28,12 +30,16 @@ module ActsAsTaggableOn::Taggable
28
30
  has_many context_taggings, -> { includes(:tag).order(taggings_order).where(context: tags_type) },
29
31
  as: :taggable,
30
32
  class_name: 'ActsAsTaggableOn::Tagging',
31
- dependent: :destroy
33
+ dependent: :destroy,
34
+ after_add: :dirtify_tag_list,
35
+ after_remove: :dirtify_tag_list
32
36
 
33
37
  has_many context_tags, -> { order(taggings_order) },
34
38
  class_name: 'ActsAsTaggableOn::Tag',
35
39
  through: context_taggings,
36
40
  source: :tag
41
+
42
+ attribute "#{tags_type.singularize}_list".to_sym, ActsAsTaggableOn::Taggable::TagListType.new
37
43
  end
38
44
 
39
45
  taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -42,12 +48,30 @@ module ActsAsTaggableOn::Taggable
42
48
  end
43
49
 
44
50
  def #{tag_type}_list=(new_tags)
51
+ parsed_new_list = ActsAsTaggableOn.default_parser.new(new_tags).parse
52
+
53
+ if self.class.preserve_tag_order? || (parsed_new_list.sort != #{tag_type}_list.sort)
54
+ if ActsAsTaggableOn::Utils.legacy_activerecord?
55
+ set_attribute_was("#{tag_type}_list", #{tag_type}_list)
56
+ else
57
+ unless #{tag_type}_list_changed?
58
+ @attributes["#{tag_type}_list"] = ActiveModel::Attribute.from_user("#{tag_type}_list", #{tag_type}_list, ActsAsTaggableOn::Taggable::TagListType.new)
59
+ end
60
+ end
61
+ write_attribute("#{tag_type}_list", parsed_new_list)
62
+ end
63
+
45
64
  set_tag_list_on('#{tags_type}', new_tags)
46
65
  end
47
66
 
48
67
  def all_#{tags_type}_list
49
68
  all_tags_list_on('#{tags_type}')
50
69
  end
70
+
71
+ private
72
+ def dirtify_tag_list(tagging)
73
+ attribute_will_change! tagging.context.singularize+"_list"
74
+ end
51
75
  RUBY
52
76
  end
53
77
  end
@@ -86,9 +110,8 @@ module ActsAsTaggableOn::Taggable
86
110
  def tagged_with(tags, options = {})
87
111
  tag_list = ActsAsTaggableOn.default_parser.new(tags).parse
88
112
  options = options.dup
89
- empty_result = where('1 = 0')
90
113
 
91
- return empty_result if tag_list.empty?
114
+ return none if tag_list.empty?
92
115
 
93
116
  ::ActsAsTaggableOn::Taggable::TaggedWithQuery.build(self, ActsAsTaggableOn::Tag, ActsAsTaggableOn::Tagging, tag_list, options)
94
117
  end
@@ -161,7 +184,7 @@ module ActsAsTaggableOn::Taggable
161
184
 
162
185
  if ActsAsTaggableOn::Utils.using_postgresql?
163
186
  group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
164
- scope.order("max(#{tagging_table_name}.created_at)").group(group_columns)
187
+ scope.order(Arel.sql("max(#{tagging_table_name}.created_at)")).group(group_columns)
165
188
  else
166
189
  scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}")
167
190
  end.to_a
@@ -181,30 +204,19 @@ module ActsAsTaggableOn::Taggable
181
204
  add_custom_context(context)
182
205
 
183
206
  variable_name = "@#{context.to_s.singularize}_list"
184
- process_dirty_object(context, new_list) unless custom_contexts.include?(context.to_s)
185
207
 
186
- instance_variable_set(variable_name, ActsAsTaggableOn.default_parser.new(new_list).parse)
208
+ parsed_new_list = ActsAsTaggableOn.default_parser.new(new_list).parse
209
+
210
+ instance_variable_set(variable_name, parsed_new_list)
187
211
  end
188
212
 
189
213
  def tagging_contexts
190
214
  self.class.tag_types.map(&:to_s) + custom_contexts
191
215
  end
192
216
 
193
- def process_dirty_object(context, new_list)
194
- value = new_list.is_a?(Array) ? ActsAsTaggableOn::TagList.new(new_list) : new_list
195
- attrib = "#{context.to_s.singularize}_list"
196
-
197
- if changed_attributes.include?(attrib)
198
- # The attribute already has an unsaved change.
199
- old = changed_attributes[attrib]
200
- @changed_attributes.delete(attrib) if old.to_s == value.to_s
201
- else
202
- old = tag_list_on(context)
203
- if self.class.preserve_tag_order
204
- @changed_attributes[attrib] = old if old.to_s != value.to_s
205
- else
206
- @changed_attributes[attrib] = old.to_s if old.sort != ActsAsTaggableOn.default_parser.new(value).parse.sort
207
- end
217
+ def taggable_tenant
218
+ if self.class.tenant_column
219
+ public_send(self.class.tenant_column)
208
220
  end
209
221
  end
210
222
 
@@ -266,7 +278,11 @@ module ActsAsTaggableOn::Taggable
266
278
 
267
279
  # Create new taggings:
268
280
  new_tags.each do |tag|
269
- taggings.create!(tag_id: tag.id, context: context.to_s, taggable: self)
281
+ if taggable_tenant
282
+ taggings.create!(tag_id: tag.id, context: context.to_s, taggable: self, tenant: taggable_tenant)
283
+ else
284
+ taggings.create!(tag_id: tag.id, context: context.to_s, taggable: self)
285
+ end
270
286
  end
271
287
  end
272
288
 
@@ -315,3 +331,4 @@ module ActsAsTaggableOn::Taggable
315
331
  end
316
332
  end
317
333
  end
334
+
@@ -49,7 +49,7 @@ module ActsAsTaggableOn::Taggable
49
49
  end
50
50
 
51
51
  def owner_tags_on(owner, context)
52
- scope = owner_tags(owner).where(
52
+ owner_tags(owner).where(
53
53
  "#{ActsAsTaggableOn::Tagging.table_name}" => {
54
54
  context: context
55
55
  }
@@ -49,7 +49,7 @@ module ActsAsTaggableOn::Taggable
49
49
  private
50
50
 
51
51
  def exclude_self(klass, id)
52
- "#{klass.table_name}.#{klass.primary_key} != #{id} AND" if [self.class.base_class, self.class].include? klass
52
+ "#{klass.arel_table[klass.primary_key].not_eq(id).to_sql} AND" if [self.class.base_class, self.class].include? klass
53
53
  end
54
54
 
55
55
  def group_columns(klass)
@@ -0,0 +1,4 @@
1
+ module ActsAsTaggableOn::Taggable
2
+ class TagListType < ActiveModel::Type::Value
3
+ end
4
+ end
@@ -49,12 +49,10 @@ module ActsAsTaggableOn::Taggable::TaggedWithQuery
49
49
  end
50
50
 
51
51
  if options[:on].present?
52
- on_condition = on_condition.and(tagging_alias[:context].lteq(options[:on]))
52
+ on_condition = on_condition.and(tagging_alias[:context].eq(options[:on]))
53
53
  end
54
54
 
55
55
  if (owner = options[:owned_by]).present?
56
- owner_table = owner.class.base_class.arel_table
57
-
58
56
  on_condition = on_condition.and(tagging_alias[:tagger_id].eq(owner.id))
59
57
  .and(tagging_alias[:tagger_type].eq(owner.class.base_class.to_s))
60
58
  end
@@ -75,7 +73,7 @@ module ActsAsTaggableOn::Taggable::TaggedWithQuery
75
73
  end
76
74
 
77
75
  if options[:on].present?
78
- on_condition = on_condition.and(tagging_arel_table[:context].lteq(options[:on]))
76
+ on_condition = on_condition.and(tagging_arel_table[:context].eq(options[:on]))
79
77
  end
80
78
 
81
79
  on_condition
@@ -3,7 +3,7 @@ module ActsAsTaggableOn::Taggable::TaggedWithQuery
3
3
  def build
4
4
  taggable_model.select(all_fields)
5
5
  .where(model_has_at_least_one_tag)
6
- .order(order_conditions)
6
+ .order(Arel.sql(order_conditions))
7
7
  .readonly(false)
8
8
  end
9
9
 
@@ -14,9 +14,6 @@ module ActsAsTaggableOn::Taggable::TaggedWithQuery
14
14
  end
15
15
 
16
16
  def model_has_at_least_one_tag
17
- tagging_alias = tagging_arel_table.alias(alias_name(tag_list))
18
-
19
-
20
17
  tagging_arel_table.project(Arel.star).where(at_least_one_tag).exists
21
18
  end
22
19
 
@@ -38,12 +35,10 @@ module ActsAsTaggableOn::Taggable::TaggedWithQuery
38
35
  end
39
36
 
40
37
  if options[:on].present?
41
- exists_contition = exists_contition.and(tagging_arel_table[:context].lteq(options[:on]))
38
+ exists_contition = exists_contition.and(tagging_arel_table[:context].eq(options[:on]))
42
39
  end
43
40
 
44
41
  if (owner = options[:owned_by]).present?
45
- owner_table = owner.class.base_class.arel_table
46
-
47
42
  exists_contition = exists_contition.and(tagging_arel_table[:tagger_id].eq(owner.id))
48
43
  .and(tagging_arel_table[:tagger_type].eq(owner.class.base_class.to_s))
49
44
  end