acts-as-taggable-on 8.1.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/spec.yml +15 -34
  3. data/Appraisals +13 -13
  4. data/CHANGELOG.md +13 -3
  5. data/README.md +6 -6
  6. data/acts-as-taggable-on.gemspec +2 -2
  7. data/db/migrate/1_acts_as_taggable_on_migration.rb +5 -7
  8. data/db/migrate/2_add_missing_unique_indices.rb +6 -8
  9. data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +3 -6
  10. data/db/migrate/4_add_missing_taggable_index.rb +5 -7
  11. data/db/migrate/5_change_collation_for_tag_names.rb +4 -6
  12. data/db/migrate/6_add_missing_indexes_on_taggings.rb +15 -13
  13. data/db/migrate/7_add_tenant_to_taggings.rb +7 -10
  14. data/docker-compose.yml +15 -0
  15. data/gemfiles/activerecord_6.0.gemfile +5 -8
  16. data/gemfiles/activerecord_6.1.gemfile +3 -8
  17. data/gemfiles/{activerecord_5.0.gemfile → activerecord_7.0.gemfile} +6 -9
  18. data/lib/acts_as_taggable_on/default_parser.rb +8 -10
  19. data/lib/acts_as_taggable_on/engine.rb +2 -0
  20. data/lib/acts_as_taggable_on/generic_parser.rb +2 -0
  21. data/lib/acts_as_taggable_on/tag.rb +30 -30
  22. data/lib/acts_as_taggable_on/tag_list.rb +8 -11
  23. data/lib/acts_as_taggable_on/taggable/cache.rb +64 -62
  24. data/lib/acts_as_taggable_on/taggable/collection.rb +178 -142
  25. data/lib/acts_as_taggable_on/taggable/core.rb +248 -244
  26. data/lib/acts_as_taggable_on/taggable/ownership.rb +110 -98
  27. data/lib/acts_as_taggable_on/taggable/related.rb +60 -47
  28. data/lib/acts_as_taggable_on/taggable/tag_list_type.rb +6 -2
  29. data/lib/acts_as_taggable_on/taggable/tagged_with_query/all_tags_query.rb +110 -106
  30. data/lib/acts_as_taggable_on/taggable/tagged_with_query/any_tags_query.rb +57 -53
  31. data/lib/acts_as_taggable_on/taggable/tagged_with_query/exclude_tags_query.rb +63 -60
  32. data/lib/acts_as_taggable_on/taggable/tagged_with_query/query_base.rb +54 -46
  33. data/lib/acts_as_taggable_on/taggable/tagged_with_query.rb +14 -8
  34. data/lib/acts_as_taggable_on/taggable.rb +14 -14
  35. data/lib/acts_as_taggable_on/tagger.rb +9 -5
  36. data/lib/acts_as_taggable_on/tagging.rb +6 -4
  37. data/lib/acts_as_taggable_on/tags_helper.rb +3 -1
  38. data/lib/acts_as_taggable_on/utils.rb +4 -2
  39. data/lib/acts_as_taggable_on/version.rb +3 -1
  40. data/spec/support/database.rb +36 -26
  41. metadata +13 -14
  42. data/gemfiles/activerecord_5.1.gemfile +0 -21
  43. data/gemfiles/activerecord_5.2.gemfile +0 -21
@@ -1,48 +1,51 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'tagged_with_query'
2
4
  require_relative 'tag_list_type'
3
5
 
4
- module ActsAsTaggableOn::Taggable
5
- module Core
6
+ module ActsAsTaggableOn
7
+ module Taggable
8
+ module Core
9
+ def self.included(base)
10
+ base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
6
11
 
7
- def self.included(base)
8
- base.extend ActsAsTaggableOn::Taggable::Core::ClassMethods
12
+ base.class_eval do
13
+ attr_writer :custom_contexts
9
14
 
10
- base.class_eval do
11
- attr_writer :custom_contexts
12
- after_save :save_tags
13
- end
15
+ after_save :save_tags
16
+ end
14
17
 
15
- base.initialize_acts_as_taggable_on_core
16
- end
18
+ base.initialize_acts_as_taggable_on_core
19
+ end
17
20
 
18
- module ClassMethods
19
- def initialize_acts_as_taggable_on_core
20
- include taggable_mixin
21
- tag_types.map(&:to_s).each do |tags_type|
22
- tag_type = tags_type.to_s.singularize
23
- context_taggings = "#{tag_type}_taggings".to_sym
24
- context_tags = tags_type.to_sym
25
- taggings_order = (preserve_tag_order? ? "#{ActsAsTaggableOn::Tagging.table_name}.id" : [])
26
-
27
- class_eval do
28
- # when preserving tag order, include order option so that for a 'tags' context
29
- # the associations tag_taggings & tags are always returned in created order
30
- has_many context_taggings, -> { includes(:tag).order(taggings_order).where(context: tags_type) },
31
- as: :taggable,
32
- class_name: 'ActsAsTaggableOn::Tagging',
33
- dependent: :destroy,
34
- after_add: :dirtify_tag_list,
35
- after_remove: :dirtify_tag_list
36
-
37
- has_many context_tags, -> { order(taggings_order) },
38
- class_name: 'ActsAsTaggableOn::Tag',
39
- through: context_taggings,
40
- source: :tag
41
-
42
- attribute "#{tags_type.singularize}_list".to_sym, ActsAsTaggableOn::Taggable::TagListType.new
43
- end
21
+ module ClassMethods
22
+ def initialize_acts_as_taggable_on_core
23
+ include taggable_mixin
24
+ tag_types.map(&:to_s).each do |tags_type|
25
+ tag_type = tags_type.to_s.singularize
26
+ context_taggings = "#{tag_type}_taggings".to_sym
27
+ context_tags = tags_type.to_sym
28
+ taggings_order = (preserve_tag_order? ? "#{ActsAsTaggableOn::Tagging.table_name}.id" : [])
29
+
30
+ class_eval do
31
+ # when preserving tag order, include order option so that for a 'tags' context
32
+ # the associations tag_taggings & tags are always returned in created order
33
+ has_many context_taggings, -> { includes(:tag).order(taggings_order).where(context: tags_type) },
34
+ as: :taggable,
35
+ class_name: 'ActsAsTaggableOn::Tagging',
36
+ dependent: :destroy,
37
+ after_add: :dirtify_tag_list,
38
+ after_remove: :dirtify_tag_list
39
+
40
+ has_many context_tags, -> { order(taggings_order) },
41
+ class_name: 'ActsAsTaggableOn::Tag',
42
+ through: context_taggings,
43
+ source: :tag
44
+
45
+ attribute "#{tags_type.singularize}_list".to_sym, ActsAsTaggableOn::Taggable::TagListType.new
46
+ end
44
47
 
45
- taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1
48
+ taggable_mixin.class_eval <<-RUBY, __FILE__, __LINE__ + 1
46
49
  def #{tag_type}_list
47
50
  tag_list_on('#{tags_type}')
48
51
  end
@@ -51,12 +54,8 @@ module ActsAsTaggableOn::Taggable
51
54
  parsed_new_list = ActsAsTaggableOn.default_parser.new(new_tags).parse
52
55
 
53
56
  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
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)
60
59
  end
61
60
  write_attribute("#{tag_type}_list", parsed_new_list)
62
61
  end
@@ -72,263 +71,268 @@ module ActsAsTaggableOn::Taggable
72
71
  def dirtify_tag_list(tagging)
73
72
  attribute_will_change! tagging.context.singularize+"_list"
74
73
  end
75
- RUBY
74
+ RUBY
75
+ end
76
+ end
77
+
78
+ def taggable_on(preserve_tag_order, *tag_types)
79
+ super(preserve_tag_order, *tag_types)
80
+ initialize_acts_as_taggable_on_core
76
81
  end
77
- end
78
82
 
79
- def taggable_on(preserve_tag_order, *tag_types)
80
- super(preserve_tag_order, *tag_types)
81
- initialize_acts_as_taggable_on_core
83
+ # all column names are necessary for PostgreSQL group clause
84
+ def grouped_column_names_for(object)
85
+ object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(', ')
86
+ end
87
+
88
+ ##
89
+ # Return a scope of objects that are tagged with the specified tags.
90
+ #
91
+ # @param tags The tags that we want to query for
92
+ # @param [Hash] options A hash of options to alter you query:
93
+ # * <tt>:exclude</tt> - if set to true, return objects that are *NOT* tagged with the specified tags
94
+ # * <tt>:any</tt> - if set to true, return objects that are tagged with *ANY* of the specified tags
95
+ # * <tt>:order_by_matching_tag_count</tt> - if set to true and used with :any, sort by objects matching the most tags, descending
96
+ # * <tt>:match_all</tt> - if set to true, return objects that are *ONLY* tagged with the specified tags
97
+ # * <tt>:owned_by</tt> - return objects that are *ONLY* owned by the owner
98
+ # * <tt>:start_at</tt> - Restrict the tags to those created after a certain time
99
+ # * <tt>:end_at</tt> - Restrict the tags to those created before a certain time
100
+ #
101
+ # Example:
102
+ # User.tagged_with(["awesome", "cool"]) # Users that are tagged with awesome and cool
103
+ # User.tagged_with(["awesome", "cool"], :exclude => true) # Users that are not tagged with awesome or cool
104
+ # User.tagged_with(["awesome", "cool"], :any => true) # Users that are tagged with awesome or cool
105
+ # User.tagged_with(["awesome", "cool"], :any => true, :order_by_matching_tag_count => true) # Sort by users who match the most tags, descending
106
+ # User.tagged_with(["awesome", "cool"], :match_all => true) # Users that are tagged with just awesome and cool
107
+ # User.tagged_with(["awesome", "cool"], :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo'
108
+ # User.tagged_with(["awesome", "cool"], :owned_by => foo, :start_at => Date.today ) # Users that are tagged with just awesome, cool by 'foo' and starting today
109
+ def tagged_with(tags, options = {})
110
+ tag_list = ActsAsTaggableOn.default_parser.new(tags).parse
111
+ options = options.dup
112
+
113
+ return none if tag_list.empty?
114
+
115
+ ::ActsAsTaggableOn::Taggable::TaggedWithQuery.build(self, ActsAsTaggableOn::Tag, ActsAsTaggableOn::Tagging,
116
+ tag_list, options)
117
+ end
118
+
119
+ def is_taggable?
120
+ true
121
+ end
122
+
123
+ def taggable_mixin
124
+ @taggable_mixin ||= Module.new
125
+ end
82
126
  end
83
127
 
84
128
  # all column names are necessary for PostgreSQL group clause
85
129
  def grouped_column_names_for(object)
86
- object.column_names.map { |column| "#{object.table_name}.#{column}" }.join(', ')
130
+ self.class.grouped_column_names_for(object)
87
131
  end
88
132
 
89
- ##
90
- # Return a scope of objects that are tagged with the specified tags.
91
- #
92
- # @param tags The tags that we want to query for
93
- # @param [Hash] options A hash of options to alter you query:
94
- # * <tt>:exclude</tt> - if set to true, return objects that are *NOT* tagged with the specified tags
95
- # * <tt>:any</tt> - if set to true, return objects that are tagged with *ANY* of the specified tags
96
- # * <tt>:order_by_matching_tag_count</tt> - if set to true and used with :any, sort by objects matching the most tags, descending
97
- # * <tt>:match_all</tt> - if set to true, return objects that are *ONLY* tagged with the specified tags
98
- # * <tt>:owned_by</tt> - return objects that are *ONLY* owned by the owner
99
- # * <tt>:start_at</tt> - Restrict the tags to those created after a certain time
100
- # * <tt>:end_at</tt> - Restrict the tags to those created before a certain time
101
- #
102
- # Example:
103
- # User.tagged_with(["awesome", "cool"]) # Users that are tagged with awesome and cool
104
- # User.tagged_with(["awesome", "cool"], :exclude => true) # Users that are not tagged with awesome or cool
105
- # User.tagged_with(["awesome", "cool"], :any => true) # Users that are tagged with awesome or cool
106
- # User.tagged_with(["awesome", "cool"], :any => true, :order_by_matching_tag_count => true) # Sort by users who match the most tags, descending
107
- # User.tagged_with(["awesome", "cool"], :match_all => true) # Users that are tagged with just awesome and cool
108
- # User.tagged_with(["awesome", "cool"], :owned_by => foo ) # Users that are tagged with just awesome and cool by 'foo'
109
- # User.tagged_with(["awesome", "cool"], :owned_by => foo, :start_at => Date.today ) # Users that are tagged with just awesome, cool by 'foo' and starting today
110
- def tagged_with(tags, options = {})
111
- tag_list = ActsAsTaggableOn.default_parser.new(tags).parse
112
- options = options.dup
113
-
114
- return none if tag_list.empty?
115
-
116
- ::ActsAsTaggableOn::Taggable::TaggedWithQuery.build(self, ActsAsTaggableOn::Tag, ActsAsTaggableOn::Tagging, tag_list, options)
133
+ def custom_contexts
134
+ @custom_contexts ||= taggings.map(&:context).uniq
117
135
  end
118
136
 
119
137
  def is_taggable?
120
- true
138
+ self.class.is_taggable?
121
139
  end
122
140
 
123
- def taggable_mixin
124
- @taggable_mixin ||= Module.new
141
+ def add_custom_context(value)
142
+ unless custom_contexts.include?(value.to_s) || self.class.tag_types.map(&:to_s).include?(value.to_s)
143
+ custom_contexts << value.to_s
144
+ end
125
145
  end
126
- end
127
-
128
- # all column names are necessary for PostgreSQL group clause
129
- def grouped_column_names_for(object)
130
- self.class.grouped_column_names_for(object)
131
- end
132
146
 
133
- def custom_contexts
134
- @custom_contexts ||= taggings.map(&:context).uniq
135
- end
147
+ def cached_tag_list_on(context)
148
+ self["cached_#{context.to_s.singularize}_list"]
149
+ end
136
150
 
137
- def is_taggable?
138
- self.class.is_taggable?
139
- end
151
+ def tag_list_cache_set_on(context)
152
+ variable_name = "@#{context.to_s.singularize}_list"
153
+ instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
154
+ end
140
155
 
141
- def add_custom_context(value)
142
- custom_contexts << value.to_s unless custom_contexts.include?(value.to_s) or self.class.tag_types.map(&:to_s).include?(value.to_s)
143
- end
156
+ def tag_list_cache_on(context)
157
+ variable_name = "@#{context.to_s.singularize}_list"
158
+ if instance_variable_get(variable_name)
159
+ instance_variable_get(variable_name)
160
+ elsif cached_tag_list_on(context) && ensure_included_cache_methods! && self.class.caching_tag_list_on?(context)
161
+ instance_variable_set(variable_name, ActsAsTaggableOn.default_parser.new(cached_tag_list_on(context)).parse)
162
+ else
163
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name)))
164
+ end
165
+ end
144
166
 
145
- def cached_tag_list_on(context)
146
- self["cached_#{context.to_s.singularize}_list"]
147
- end
167
+ def tag_list_on(context)
168
+ add_custom_context(context)
169
+ tag_list_cache_on(context)
170
+ end
148
171
 
149
- def tag_list_cache_set_on(context)
150
- variable_name = "@#{context.to_s.singularize}_list"
151
- instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
152
- end
172
+ def all_tags_list_on(context)
173
+ variable_name = "@all_#{context.to_s.singularize}_list"
174
+ if instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
175
+ return instance_variable_get(variable_name)
176
+ end
153
177
 
154
- def tag_list_cache_on(context)
155
- variable_name = "@#{context.to_s.singularize}_list"
156
- if instance_variable_get(variable_name)
157
- instance_variable_get(variable_name)
158
- elsif cached_tag_list_on(context) && ensure_included_cache_methods! && self.class.caching_tag_list_on?(context)
159
- instance_variable_set(variable_name, ActsAsTaggableOn.default_parser.new(cached_tag_list_on(context)).parse)
160
- else
161
- instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name)))
178
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(all_tags_on(context).map(&:name)).freeze)
162
179
  end
163
- end
164
180
 
165
- def tag_list_on(context)
166
- add_custom_context(context)
167
- tag_list_cache_on(context)
168
- end
181
+ ##
182
+ # Returns all tags of a given context
183
+ def all_tags_on(context)
184
+ tagging_table_name = ActsAsTaggableOn::Tagging.table_name
169
185
 
170
- def all_tags_list_on(context)
171
- variable_name = "@all_#{context.to_s.singularize}_list"
172
- return instance_variable_get(variable_name) if instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
186
+ opts = ["#{tagging_table_name}.context = ?", context.to_s]
187
+ scope = base_tags.where(opts)
173
188
 
174
- instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(all_tags_on(context).map(&:name)).freeze)
175
- end
176
-
177
- ##
178
- # Returns all tags of a given context
179
- def all_tags_on(context)
180
- tagging_table_name = ActsAsTaggableOn::Tagging.table_name
189
+ if ActsAsTaggableOn::Utils.using_postgresql?
190
+ group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
191
+ scope.order(Arel.sql("max(#{tagging_table_name}.created_at)")).group(group_columns)
192
+ else
193
+ scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}")
194
+ end.to_a
195
+ end
181
196
 
182
- opts = ["#{tagging_table_name}.context = ?", context.to_s]
183
- scope = base_tags.where(opts)
197
+ ##
198
+ # Returns all tags that are not owned of a given context
199
+ def tags_on(context)
200
+ scope = base_tags.where([
201
+ "#{ActsAsTaggableOn::Tagging.table_name}.context = ? AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id IS NULL", context.to_s
202
+ ])
203
+ # when preserving tag order, return tags in created order
204
+ # if we added the order to the association this would always apply
205
+ scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") if self.class.preserve_tag_order?
206
+ scope
207
+ end
184
208
 
185
- if ActsAsTaggableOn::Utils.using_postgresql?
186
- group_columns = grouped_column_names_for(ActsAsTaggableOn::Tag)
187
- scope.order(Arel.sql("max(#{tagging_table_name}.created_at)")).group(group_columns)
188
- else
189
- scope.group("#{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key}")
190
- end.to_a
191
- end
209
+ def set_tag_list_on(context, new_list)
210
+ add_custom_context(context)
192
211
 
193
- ##
194
- # Returns all tags that are not owned of a given context
195
- def tags_on(context)
196
- scope = base_tags.where(["#{ActsAsTaggableOn::Tagging.table_name}.context = ? AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id IS NULL", context.to_s])
197
- # when preserving tag order, return tags in created order
198
- # if we added the order to the association this would always apply
199
- scope = scope.order("#{ActsAsTaggableOn::Tagging.table_name}.id") if self.class.preserve_tag_order?
200
- scope
201
- end
212
+ variable_name = "@#{context.to_s.singularize}_list"
202
213
 
203
- def set_tag_list_on(context, new_list)
204
- add_custom_context(context)
214
+ parsed_new_list = ActsAsTaggableOn.default_parser.new(new_list).parse
205
215
 
206
- variable_name = "@#{context.to_s.singularize}_list"
216
+ instance_variable_set(variable_name, parsed_new_list)
217
+ end
207
218
 
208
- parsed_new_list = ActsAsTaggableOn.default_parser.new(new_list).parse
219
+ def tagging_contexts
220
+ self.class.tag_types.map(&:to_s) + custom_contexts
221
+ end
209
222
 
210
- instance_variable_set(variable_name, parsed_new_list)
211
- end
223
+ def taggable_tenant
224
+ public_send(self.class.tenant_column) if self.class.tenant_column
225
+ end
212
226
 
213
- def tagging_contexts
214
- self.class.tag_types.map(&:to_s) + custom_contexts
215
- end
227
+ def reload(*args)
228
+ self.class.tag_types.each do |context|
229
+ instance_variable_set("@#{context.to_s.singularize}_list", nil)
230
+ instance_variable_set("@all_#{context.to_s.singularize}_list", nil)
231
+ end
216
232
 
217
- def taggable_tenant
218
- if self.class.tenant_column
219
- public_send(self.class.tenant_column)
233
+ super(*args)
220
234
  end
221
- end
222
235
 
223
- def reload(*args)
224
- self.class.tag_types.each do |context|
225
- instance_variable_set("@#{context.to_s.singularize}_list", nil)
226
- instance_variable_set("@all_#{context.to_s.singularize}_list", nil)
236
+ ##
237
+ # Find existing tags or create non-existing tags
238
+ def load_tags(tag_list)
239
+ ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list)
227
240
  end
228
241
 
229
- super(*args)
230
- end
231
-
232
- ##
233
- # Find existing tags or create non-existing tags
234
- def load_tags(tag_list)
235
- ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list)
236
- end
242
+ def save_tags
243
+ tagging_contexts.each do |context|
244
+ next unless tag_list_cache_set_on(context)
237
245
 
238
- def save_tags
239
- tagging_contexts.each do |context|
240
- next unless tag_list_cache_set_on(context)
241
- # List of currently assigned tag names
242
- tag_list = tag_list_cache_on(context).uniq
246
+ # List of currently assigned tag names
247
+ tag_list = tag_list_cache_on(context).uniq
243
248
 
244
- # Find existing tags or create non-existing tags:
245
- tags = find_or_create_tags_from_list_with_context(tag_list, context)
249
+ # Find existing tags or create non-existing tags:
250
+ tags = find_or_create_tags_from_list_with_context(tag_list, context)
246
251
 
247
- # Tag objects for currently assigned tags
248
- current_tags = tags_on(context)
252
+ # Tag objects for currently assigned tags
253
+ current_tags = tags_on(context)
249
254
 
250
- # Tag maintenance based on whether preserving the created order of tags
251
- if self.class.preserve_tag_order?
252
- old_tags, new_tags = current_tags - tags, tags - current_tags
255
+ # Tag maintenance based on whether preserving the created order of tags
256
+ old_tags = current_tags - tags
257
+ new_tags = tags - current_tags
258
+ if self.class.preserve_tag_order?
253
259
 
254
- shared_tags = current_tags & tags
260
+ shared_tags = current_tags & tags
255
261
 
256
- if shared_tags.any? && tags[0...shared_tags.size] != shared_tags
257
- index = shared_tags.each_with_index { |_, i| break i unless shared_tags[i] == tags[i] }
262
+ if shared_tags.any? && tags[0...shared_tags.size] != shared_tags
263
+ index = shared_tags.each_with_index do |_, i|
264
+ break i unless shared_tags[i] == tags[i]
265
+ end
258
266
 
259
- # Update arrays of tag objects
260
- old_tags |= current_tags[index...current_tags.size]
261
- new_tags |= current_tags[index...current_tags.size] & shared_tags
267
+ # Update arrays of tag objects
268
+ old_tags |= current_tags[index...current_tags.size]
269
+ new_tags |= current_tags[index...current_tags.size] & shared_tags
262
270
 
263
- # Order the array of tag objects to match the tag list
264
- new_tags = tags.map do |t|
265
- new_tags.find { |n| n.name.downcase == t.name.downcase }
266
- end.compact
271
+ # Order the array of tag objects to match the tag list
272
+ new_tags = tags.map do |t|
273
+ new_tags.find { |n| n.name.downcase == t.name.downcase }
274
+ end.compact
275
+ end
276
+ else
277
+ # Delete discarded tags and create new tags
267
278
  end
268
- else
269
- # Delete discarded tags and create new tags
270
- old_tags = current_tags - tags
271
- new_tags = tags - current_tags
272
- end
273
279
 
274
- # Destroy old taggings:
275
- if old_tags.present?
276
- taggings.not_owned.by_context(context).where(tag_id: old_tags).destroy_all
277
- end
280
+ # Destroy old taggings:
281
+ taggings.not_owned.by_context(context).where(tag_id: old_tags).destroy_all if old_tags.present?
278
282
 
279
- # Create new taggings:
280
- new_tags.each do |tag|
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)
283
+ # Create new taggings:
284
+ new_tags.each do |tag|
285
+ if taggable_tenant
286
+ taggings.create!(tag_id: tag.id, context: context.to_s, taggable: self, tenant: taggable_tenant)
287
+ else
288
+ taggings.create!(tag_id: tag.id, context: context.to_s, taggable: self)
289
+ end
285
290
  end
286
291
  end
287
- end
288
292
 
289
- true
290
- end
293
+ true
294
+ end
291
295
 
292
- private
296
+ private
293
297
 
294
- def ensure_included_cache_methods!
295
- self.class.columns
296
- end
298
+ def ensure_included_cache_methods!
299
+ self.class.columns
300
+ end
297
301
 
298
- # Filters the tag lists from the attribute names.
299
- def attributes_for_update(attribute_names)
300
- tag_lists = tag_types.map {|tags_type| "#{tags_type.to_s.singularize}_list"}
301
- super.delete_if {|attr| tag_lists.include? attr }
302
- end
302
+ # Filters the tag lists from the attribute names.
303
+ def attributes_for_update(attribute_names)
304
+ tag_lists = tag_types.map { |tags_type| "#{tags_type.to_s.singularize}_list" }
305
+ super.delete_if { |attr| tag_lists.include? attr }
306
+ end
303
307
 
304
- # Filters the tag lists from the attribute names.
305
- def attributes_for_create(attribute_names)
306
- tag_lists = tag_types.map {|tags_type| "#{tags_type.to_s.singularize}_list"}
307
- super.delete_if {|attr| tag_lists.include? attr }
308
- end
308
+ # Filters the tag lists from the attribute names.
309
+ def attributes_for_create(attribute_names)
310
+ tag_lists = tag_types.map { |tags_type| "#{tags_type.to_s.singularize}_list" }
311
+ super.delete_if { |attr| tag_lists.include? attr }
312
+ end
309
313
 
310
- ##
311
- # Override this hook if you wish to subclass {ActsAsTaggableOn::Tag} --
312
- # context is provided so that you may conditionally use a Tag subclass
313
- # only for some contexts.
314
- #
315
- # @example Custom Tag class for one context
316
- # class Company < ActiveRecord::Base
317
- # acts_as_taggable_on :markets, :locations
318
- #
319
- # def find_or_create_tags_from_list_with_context(tag_list, context)
320
- # if context.to_sym == :markets
321
- # MarketTag.find_or_create_all_with_like_by_name(tag_list)
322
- # else
323
- # super
324
- # end
325
- # end
326
- #
327
- # @param [Array<String>] tag_list Tags to find or create
328
- # @param [Symbol] context The tag context for the tag_list
329
- def find_or_create_tags_from_list_with_context(tag_list, _context)
330
- load_tags(tag_list)
314
+ ##
315
+ # Override this hook if you wish to subclass {ActsAsTaggableOn::Tag} --
316
+ # context is provided so that you may conditionally use a Tag subclass
317
+ # only for some contexts.
318
+ #
319
+ # @example Custom Tag class for one context
320
+ # class Company < ActiveRecord::Base
321
+ # acts_as_taggable_on :markets, :locations
322
+ #
323
+ # def find_or_create_tags_from_list_with_context(tag_list, context)
324
+ # if context.to_sym == :markets
325
+ # MarketTag.find_or_create_all_with_like_by_name(tag_list)
326
+ # else
327
+ # super
328
+ # end
329
+ # end
330
+ #
331
+ # @param [Array<String>] tag_list Tags to find or create
332
+ # @param [Symbol] context The tag context for the tag_list
333
+ def find_or_create_tags_from_list_with_context(tag_list, _context)
334
+ load_tags(tag_list)
335
+ end
331
336
  end
332
337
  end
333
338
  end
334
-