acts-as-taggable-on-mongoid 6.0.1.4 → 6.1.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +2 -1
- data/.rubocop.yml +402 -38
- data/.ruby-version +1 -1
- data/Gemfile.lock +110 -110
- data/README.md +103 -28
- data/acts-as-taggable-on-mongoid.gemspec +5 -5
- data/lib/acts-as-taggable-on-mongoid.rb +11 -4
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_associations.rb +14 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_fields.rb +6 -1
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_hooks.rb +68 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_methods.rb +36 -22
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_migration.rb +46 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_model.rb +3 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_scopes.rb +5 -2
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tag_validations.rb +3 -1
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_associations.rb +20 -2
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_fields.rb +6 -2
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_methods.rb +4 -2
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_migration.rb +46 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_model.rb +2 -0
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_scopes.rb +9 -5
- data/lib/acts_as_taggable_on_mongoid/models/concerns/tagging_validations.rb +4 -6
- data/lib/acts_as_taggable_on_mongoid/tag_list.rb +91 -4
- data/lib/acts_as_taggable_on_mongoid/taggable.rb +22 -3
- data/lib/acts_as_taggable_on_mongoid/taggable/cache.rb +30 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/changeable.rb +5 -4
- data/lib/acts_as_taggable_on_mongoid/taggable/core.rb +157 -34
- data/lib/acts_as_taggable_on_mongoid/taggable/list_tags.rb +1 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition.rb +43 -50
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/attributes.rb +70 -6
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/changeable.rb +52 -39
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/list_methods.rb +77 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/names.rb +12 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tagged_with_query/all_tags_query.rb +1 -1
- data/lib/acts_as_taggable_on_mongoid/taggable/tagged_with_query/any_tags_query.rb +1 -1
- data/lib/acts_as_taggable_on_mongoid/taggable/tagged_with_query/exclude_tags_query.rb +1 -1
- data/lib/acts_as_taggable_on_mongoid/taggable/tagged_with_query/match_all_tags_query.rb +1 -1
- data/lib/acts_as_taggable_on_mongoid/taggable/tagger_relation.rb +53 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/utils/tag_list_diff.rb +9 -7
- data/lib/acts_as_taggable_on_mongoid/tagger.rb +67 -0
- data/lib/acts_as_taggable_on_mongoid/tagger/tag_methods.rb +74 -0
- data/lib/acts_as_taggable_on_mongoid/tagger_tag_list.rb +171 -0
- data/lib/acts_as_taggable_on_mongoid/version.rb +1 -1
- metadata +43 -29
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsTaggableOnMongoid
|
4
|
+
module Models
|
5
|
+
module Concerns
|
6
|
+
# A module that defines methods to migrate a Tag model.
|
7
|
+
#
|
8
|
+
# Mongoid does not have a standardized migration scheme, but migrations of one kind or another
|
9
|
+
# are often a fact of life, and are in this situation because of the need to change an existing
|
10
|
+
# index.
|
11
|
+
#
|
12
|
+
# Using whatever migration methodology you prefer, you need to run the appropriate migration method
|
13
|
+
# or methods on the Tag module used by your project.
|
14
|
+
#
|
15
|
+
# The migrations are named for the ActsAsTaggableMongoid versions upon which they need to be run.
|
16
|
+
# Run the correct migration(s) for the version of ActsAsTaggableOnMongoid you are currently using
|
17
|
+
# This module does not and cannot verify the version you are migrating from nor if the migration
|
18
|
+
# has been run before. Doing so is assumed to be the responsibility of your chosen
|
19
|
+
# Migration methodology.
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# # When a migration is needed, the method "up" is called:
|
24
|
+
# def up
|
25
|
+
# TaggingModel.include ActsAsTaggableOnMongoid::Models::Concerns::TaggingMigration
|
26
|
+
# TaggingModel.atom_migrate_up_6_0_1_to_6_1_1
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# The migration methods should only be run once if possible, but every reasonable effort is made to
|
30
|
+
# ensure that the migration methods are safe to re-run.
|
31
|
+
module TaggingMigration
|
32
|
+
extend ActiveSupport::Concern
|
33
|
+
|
34
|
+
class_methods do
|
35
|
+
# :reek:UncommunicativeMethodName - The name indicates what gem versions the migration is from/to
|
36
|
+
def atom_migrate_up_6_0_1_to_6_1_1
|
37
|
+
indexes = collection.indexes
|
38
|
+
indexes.drop_one "tagging_taggable_context_tag_name" if indexes.get "tagging_taggable_context_tag_name"
|
39
|
+
|
40
|
+
create_indexes
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsTaggableOnMongoid
|
2
4
|
module Models
|
3
5
|
module Concerns
|
@@ -8,12 +10,14 @@ module ActsAsTaggableOnMongoid
|
|
8
10
|
DEFAULT_CONTEXT = "tags"
|
9
11
|
|
10
12
|
included do
|
11
|
-
#
|
12
|
-
|
13
|
+
# aliased scopes from ActsAsTaggable
|
14
|
+
scope :owned_by, ->(tagger) { tagged_by(tagger) }
|
15
|
+
scope :not_owned, -> { tagged_by(nil) }
|
13
16
|
|
14
|
-
scope :
|
15
|
-
scope :
|
16
|
-
scope :
|
17
|
+
scope :by_tag_types, ->(*tag_types) { where(:context.in => Array.wrap(tag_types.presence || DEFAULT_CONTEXT)) }
|
18
|
+
scope :by_tag_type, ->(tag_type = DEFAULT_CONTEXT) { by_tag_types(tag_type.to_s) }
|
19
|
+
scope :tagged_by, ->(tagger) { tagger ? where(tagger: tagger) : where(:tagger_id.exists => false) }
|
20
|
+
scope :for_tag, ->(tag_definition) { where(taggable_type: tag_definition.owner.name).by_tag_type(tag_definition.tag_type) }
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsTaggableOnMongoid
|
2
4
|
module Models
|
3
5
|
module Concerns
|
@@ -8,13 +10,9 @@ module ActsAsTaggableOnMongoid
|
|
8
10
|
included do
|
9
11
|
validates :tag_name, presence: true
|
10
12
|
validates :context, presence: true
|
11
|
-
validates :tag, presence: true
|
12
|
-
validates :taggable, presence: true
|
13
13
|
|
14
|
-
|
15
|
-
validates :
|
16
|
-
# validates :tag_id, uniqueness: {scope: [:taggable_type, :taggable_id, :context, :tagger_id, :tagger_type]}
|
17
|
-
validates :tag_id, uniqueness: { scope: %i[taggable_type taggable_id context] }
|
14
|
+
validates :tag_name, uniqueness: { scope: %i[taggable_id taggable_type context tagger_id tagger_type] }
|
15
|
+
validates :tag_id, uniqueness: { scope: %i[taggable_id taggable_type context tagger_id tagger_type] }
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -12,6 +12,16 @@ module ActsAsTaggableOnMongoid
|
|
12
12
|
#
|
13
13
|
# If the input value(s) are to be parsed, then all values passed in are parsed.
|
14
14
|
#
|
15
|
+
# Options:
|
16
|
+
# parse - True/False - indicates if all of the strings that are passed in are to be parsed
|
17
|
+
# to split them into an array of strings.
|
18
|
+
# Please note - if the passed in value is an array of strings, every string in the array
|
19
|
+
# will be parsed. If it is a single array, then just that string is parsed.
|
20
|
+
# parser - Class - A class that is used to parse the passed in strings.
|
21
|
+
# If this parameter is supplied, parse is assumed to be truthy even if it is not passed in.
|
22
|
+
# tagger - object - An object that is to be used as the Tagger for the Taggable object.
|
23
|
+
# This parameter is ignored if the tag does not support Taggers.
|
24
|
+
#
|
15
25
|
# Examples:
|
16
26
|
# TagList.new(tag_definition, "value 1", "value 2")
|
17
27
|
# # > TagList<> ["value 1", "value 2"]
|
@@ -38,6 +48,40 @@ module ActsAsTaggableOnMongoid
|
|
38
48
|
add(*args)
|
39
49
|
end
|
40
50
|
|
51
|
+
class << self
|
52
|
+
def new_taggable_list(tag_definition, taggable)
|
53
|
+
list = ActsAsTaggableOnMongoid::TagList.new(tag_definition)
|
54
|
+
|
55
|
+
list.taggable = taggable
|
56
|
+
|
57
|
+
list
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def dup
|
62
|
+
list = ActsAsTaggableOnMongoid::TagList.new(tag_definition, *self)
|
63
|
+
list.tagger = instance_variable_get(:@tagger) if instance_variable_defined?(:@tagger)
|
64
|
+
list.taggable = taggable
|
65
|
+
|
66
|
+
list
|
67
|
+
end
|
68
|
+
|
69
|
+
def tagger=(value)
|
70
|
+
return unless tag_definition.tagger?
|
71
|
+
|
72
|
+
instance_variable_set(:@tagger, value)
|
73
|
+
end
|
74
|
+
|
75
|
+
def tagger
|
76
|
+
return nil unless tag_definition.tagger?
|
77
|
+
return tag_definition.default_tagger(taggable) unless instance_variable_defined?(:@tagger)
|
78
|
+
|
79
|
+
tagger = instance_variable_get(:@tagger)
|
80
|
+
tagger = taggable&.public_send(tagger) if tagger.is_a?(Symbol)
|
81
|
+
|
82
|
+
instance_variable_set(:@tagger, tagger)
|
83
|
+
end
|
84
|
+
|
41
85
|
##
|
42
86
|
# Add tags to the tag_list. Duplicate or blank tags will be ignored.
|
43
87
|
# Use the <tt>:parse</tt> option to add an unparsed tag string.
|
@@ -53,6 +97,17 @@ module ActsAsTaggableOnMongoid
|
|
53
97
|
self
|
54
98
|
end
|
55
99
|
|
100
|
+
##
|
101
|
+
# Replaces the tags with the tags passed in.
|
102
|
+
#
|
103
|
+
# Example:
|
104
|
+
# tag_list.set("Fun", "Happy")
|
105
|
+
# tag_list.set("Fun, Happy", :parse => true)
|
106
|
+
def set(*names)
|
107
|
+
clear
|
108
|
+
add(*names)
|
109
|
+
end
|
110
|
+
|
56
111
|
# Append---Add the tag to the tag_list. This
|
57
112
|
# expression returns the tag_list itself, so several appends
|
58
113
|
# may be chained together.
|
@@ -63,7 +118,13 @@ module ActsAsTaggableOnMongoid
|
|
63
118
|
# Concatenation --- Returns a new tag list built by concatenating the
|
64
119
|
# two tag lists together to produce a third tag list.
|
65
120
|
def +(other)
|
66
|
-
|
121
|
+
dup.add(other)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Removal --- Returns a new tag list built by removing the
|
125
|
+
# passed in tag list to produce a third tag list.
|
126
|
+
def -(other)
|
127
|
+
dup.remove(other)
|
67
128
|
end
|
68
129
|
|
69
130
|
# Appends the elements of +other_tag_list+ to +self+.
|
@@ -75,6 +136,27 @@ module ActsAsTaggableOnMongoid
|
|
75
136
|
self
|
76
137
|
end
|
77
138
|
|
139
|
+
# Appends the elements of +other_tag_list+ to +self+.
|
140
|
+
def clear
|
141
|
+
notify_will_change
|
142
|
+
|
143
|
+
super
|
144
|
+
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
148
|
+
# Appends the elements of +other_tag_list+ to +self+.
|
149
|
+
def silent_concat(other_tag_list)
|
150
|
+
temp_taggable = taggable
|
151
|
+
self.taggable = nil
|
152
|
+
|
153
|
+
concat(other_tag_list)
|
154
|
+
|
155
|
+
self.taggable = temp_taggable
|
156
|
+
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
78
160
|
##
|
79
161
|
# Remove specific tags from the tag_list.
|
80
162
|
# Use the <tt>:parse</tt> option to add an unparsed tag string.
|
@@ -151,13 +233,18 @@ module ActsAsTaggableOnMongoid
|
|
151
233
|
self
|
152
234
|
end
|
153
235
|
|
154
|
-
# :reek:FeatureEnvy
|
155
|
-
# :reek:DuplicateMethodCall
|
156
236
|
def extract_and_apply_options!(args)
|
157
237
|
dup_args = args.dup
|
158
238
|
options = dup_args.extract_options!.dup
|
159
|
-
options.assert_valid_keys :parse, :parser
|
160
239
|
|
240
|
+
options.assert_valid_keys :parse, :parser, :tagger
|
241
|
+
|
242
|
+
instance_variable_set(:@tagger, options[:tagger]) if options.key?(:tagger) && tag_definition.tagger?
|
243
|
+
|
244
|
+
parse_args_values(dup_args, options)
|
245
|
+
end
|
246
|
+
|
247
|
+
def parse_args_values(dup_args, options)
|
161
248
|
options_parser = options[:parser]
|
162
249
|
run_parser = options_parser || tag_definition.parser
|
163
250
|
|
@@ -18,7 +18,14 @@ module ActsAsTaggableOnMongoid
|
|
18
18
|
# * preserve_tag_order
|
19
19
|
# If true, the _list accessor will save and returns tags in the order they are added to the object.
|
20
20
|
# * cached_in_model
|
21
|
-
#
|
21
|
+
# If true, a field is added to de-normalize/cache the list into. Can also be a hash with options:
|
22
|
+
# field: The name of the field to cache the list in
|
23
|
+
# as_list: true/false - If the cached value should be an Array or a String. No order is guaranteed
|
24
|
+
# in either case.
|
25
|
+
# Defaults to true.
|
26
|
+
# * owner_id_field
|
27
|
+
# If cached_in_model is true, if a tag is owned, this is the field that will be checked for a matching
|
28
|
+
# owner ID for tag updates and deletes.
|
22
29
|
# * force_lowercase
|
23
30
|
# If true, values stored for tags will first be downcased to make the values effectively case-insensitive
|
24
31
|
# * force_parameterize
|
@@ -34,6 +41,18 @@ module ActsAsTaggableOnMongoid
|
|
34
41
|
# can be used. If custom options like `parse` or `parser` are to be used for the default, the value
|
35
42
|
# must be passed in as an array with a hash as the last value. Like list setters, parsing is assumed.
|
36
43
|
# Example: default: ["this, is, a, list", parser: ActsAsTaggableOnMongoid::GenericParser]
|
44
|
+
# * tagger
|
45
|
+
# Multiple variants
|
46
|
+
#
|
47
|
+
# true - If simply the value `true`, the tag list supports owners. No default owner will be used when
|
48
|
+
# setting or accessing tag_lists
|
49
|
+
# Hash - A hash of values defining default options for the tag list:
|
50
|
+
# * default_tagger
|
51
|
+
# A symbol of a method on the taggable object that owns the HashList which is used to determine
|
52
|
+
# the default owner for a list if an owner is not specified.
|
53
|
+
# * tag_list_uses_default_tagger
|
54
|
+
# true/false indicating if a non-owner method that returns a tag_list should assume the default_tagger
|
55
|
+
# or return items with no owner.
|
37
56
|
|
38
57
|
##
|
39
58
|
# This is an alias for calling <tt>acts_as_taggable_on :tags</tt>.
|
@@ -110,9 +129,9 @@ module ActsAsTaggableOnMongoid
|
|
110
129
|
ActsAsTaggableOnMongoid::Taggable::Changeable,
|
111
130
|
ActsAsTaggableOnMongoid::Taggable::TaggedWith,
|
112
131
|
# include Collection - not sure we will need as done here. Need to think more on this one.
|
113
|
-
|
114
|
-
# include Ownership - TODO: Add this.
|
132
|
+
ActsAsTaggableOnMongoid::Taggable::Cache,
|
115
133
|
# include Related - TODO: Add this.
|
134
|
+
ActsAsTaggableOnMongoid::Taggable::TaggerRelation,
|
116
135
|
ActsAsTaggableOnMongoid::Taggable::ListTags].each do |include_module|
|
117
136
|
include include_module unless included_modules.include?(include_module)
|
118
137
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsTaggableOnMongoid
|
4
|
+
module Taggable
|
5
|
+
# A collection of generic methods which use the tag definition to perform actions.
|
6
|
+
#
|
7
|
+
# These methods are called by the individual tag generated methods to do their work so that
|
8
|
+
# the code can be defined in only one location and "shared" by all tags rather than putting the code
|
9
|
+
# and definitions into the dynamically defined methods directly.
|
10
|
+
#
|
11
|
+
# This module actually consists almost exclusively of utility functions
|
12
|
+
|
13
|
+
# :reek:FeatureEnvy
|
14
|
+
# :reek:UtilityFunction
|
15
|
+
module Cache
|
16
|
+
def save_cached_tag_lists
|
17
|
+
tag_types.each_value do |tag_definition|
|
18
|
+
next unless tag_definition.cached_in_model?
|
19
|
+
next unless tag_list_cache_set_on(tag_definition)
|
20
|
+
|
21
|
+
list = all_tags_list_on(tag_definition)
|
22
|
+
|
23
|
+
list = list.to_s unless tag_definition.cached_in_model_as_list?
|
24
|
+
|
25
|
+
public_send("#{tag_definition.cached_in_model_field}=", list)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -40,9 +40,9 @@ module ActsAsTaggableOnMongoid
|
|
40
40
|
tag_types.each_value do |tag_definition|
|
41
41
|
tag_list_name = tag_definition.tag_list_name
|
42
42
|
|
43
|
-
next unless
|
43
|
+
next unless public_send("#{tag_list_name}_changed?")
|
44
44
|
|
45
|
-
changed_values[tag_list_name] =
|
45
|
+
changed_values[tag_list_name] = public_send("#{tag_list_name}_change")
|
46
46
|
end
|
47
47
|
|
48
48
|
changed_values
|
@@ -60,11 +60,12 @@ module ActsAsTaggableOnMongoid
|
|
60
60
|
private
|
61
61
|
|
62
62
|
def attribute_will_change!(attribute_name)
|
63
|
-
|
63
|
+
tag_definition = tag_types.detect { |_tag_name, tag_def| tag_def.tag_list_name.to_s == attribute_name.to_s }&.last
|
64
|
+
return super if tag_definition.blank?
|
64
65
|
|
65
66
|
return if changed_attributes.key?(attribute_name)
|
66
67
|
|
67
|
-
changed_attributes[attribute_name] =
|
68
|
+
changed_attributes[attribute_name] = tag_list_cache_on(tag_definition)&.dup
|
68
69
|
end
|
69
70
|
end
|
70
71
|
end
|
@@ -22,6 +22,7 @@ module ActsAsTaggableOnMongoid
|
|
22
22
|
# attr_writer :custom_contexts
|
23
23
|
|
24
24
|
after_save :save_tags
|
25
|
+
before_save :save_cached_tag_lists
|
25
26
|
end
|
26
27
|
|
27
28
|
class_methods do
|
@@ -40,14 +41,99 @@ module ActsAsTaggableOnMongoid
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
def
|
44
|
-
super
|
44
|
+
def apply_post_processed_defaults
|
45
|
+
defaults = super
|
45
46
|
|
46
|
-
set_tag_list_defaults
|
47
|
+
defaults |= set_tag_list_defaults
|
48
|
+
|
49
|
+
defaults
|
47
50
|
end
|
48
51
|
|
49
52
|
private
|
50
53
|
|
54
|
+
def set_tag_list(tag_definition, new_tags)
|
55
|
+
dup_tags = Array.wrap(new_tags).dup
|
56
|
+
options = dup_tags.extract_options!.dup
|
57
|
+
options[:parse] = options.fetch(:parse) { true }
|
58
|
+
|
59
|
+
new_list = tag_definition.parse(*dup_tags, options)
|
60
|
+
new_list.taggable = self
|
61
|
+
new_list.tagger = tag_definition.tag_list_default_tagger(self) unless options.key?(:tagger)
|
62
|
+
|
63
|
+
mark_tag_list_changed(new_list)
|
64
|
+
tag_list_set(new_list)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_tag_list_change(tag_definition)
|
68
|
+
tag_list_name = tag_definition.tag_list_name
|
69
|
+
|
70
|
+
return nil unless public_send("#{tag_list_name}_changed?")
|
71
|
+
|
72
|
+
changed_value = new_record? ? tag_definition.default_tagger_tag_list(self) : changed_attributes[tag_list_name]
|
73
|
+
current_value = tag_list_cache_on(tag_definition)
|
74
|
+
|
75
|
+
return nil if (changed_value <=> current_value)&.zero?
|
76
|
+
|
77
|
+
tag_list_change_value(tag_definition, changed_value, current_value)
|
78
|
+
end
|
79
|
+
|
80
|
+
def tag_list_change_value(tag_definition, changed_value, current_value)
|
81
|
+
if tag_definition.tagger?
|
82
|
+
[changed_value.dup, current_value.dup]
|
83
|
+
else
|
84
|
+
[changed_value[nil].dup, current_value[nil].dup]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_tag_list_changed(tag_definition)
|
89
|
+
tag_list_name = tag_definition.tag_list_name
|
90
|
+
|
91
|
+
return false unless changed_attributes.key?(tag_list_name)
|
92
|
+
|
93
|
+
changed_value = new_record? ? tag_definition.default_tagger_tag_list(self) : changed_attributes[tag_list_name]
|
94
|
+
current_value = tag_list_cache_on(tag_definition)
|
95
|
+
|
96
|
+
!(changed_value <=> current_value)&.zero?
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_tag_list_was(tag_definition)
|
100
|
+
default_tagger = tag_definition.tag_list_default_tagger(self)
|
101
|
+
return tag_definition.default_tagger_tag_list(self)[default_tagger].dup if new_record?
|
102
|
+
|
103
|
+
tag_list_name = tag_definition.tag_list_name
|
104
|
+
|
105
|
+
if public_send "#{tag_list_name}_changed?"
|
106
|
+
changed_attributes[tag_list_name][default_tagger].dup
|
107
|
+
else
|
108
|
+
public_send(tag_list_name).dup
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_tag_lists_was(tag_definition)
|
113
|
+
return tag_definition.default_tagger_tag_list(self).dup if new_record?
|
114
|
+
|
115
|
+
tag_list_name = tag_definition.tag_list_name
|
116
|
+
|
117
|
+
if public_send "#{tag_list_name}_changed?"
|
118
|
+
changed_attributes[tag_list_name].dup
|
119
|
+
else
|
120
|
+
public_send(tag_definition.tagger_tag_lists_name).dup
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_tagger_list_was(tag_definition, tagger)
|
125
|
+
return nil unless tag_definition.tagger?
|
126
|
+
return tag_definition.default_tagger_tag_list(self)[tagger].dup if new_record?
|
127
|
+
|
128
|
+
tag_list_name = tag_definition.tag_list_name
|
129
|
+
|
130
|
+
if public_send "#{tag_list_name}_changed?"
|
131
|
+
changed_attributes[tag_list_name][tagger].dup
|
132
|
+
else
|
133
|
+
public_send(tag_definition.tagger_tag_list_name, tagger).dup
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
51
137
|
def tag_list_cache_set_on(tag_definition)
|
52
138
|
variable_name = tag_definition.tag_list_variable_name
|
53
139
|
|
@@ -66,35 +152,57 @@ module ActsAsTaggableOnMongoid
|
|
66
152
|
# end
|
67
153
|
|
68
154
|
instance_variable_get(variable_name) ||
|
69
|
-
|
155
|
+
tagger_tag_list_set(tagger_tag_list_from_taggings(tag_definition, all_tags_on(tag_definition)))
|
156
|
+
end
|
157
|
+
|
158
|
+
def tagger_tag_list_from_taggings(tag_definition, taggings)
|
159
|
+
tagger_tag_list = ActsAsTaggableOnMongoid::TaggerTagList.new(tag_definition, self)
|
160
|
+
|
161
|
+
taggings.each do |tagging|
|
162
|
+
tagger_tag_list[tagging.tagger].silent_concat [tagging.tag_name]
|
163
|
+
end
|
164
|
+
|
165
|
+
tagger_tag_list
|
70
166
|
end
|
71
167
|
|
72
168
|
def tag_list_on(tag_definition)
|
73
169
|
# add_custom_context(tag_definition)
|
74
170
|
|
75
|
-
tag_list_cache_on(tag_definition)
|
171
|
+
tag_list_cache_on(tag_definition)[tag_definition.tag_list_default_tagger(self)]
|
76
172
|
end
|
77
173
|
|
78
174
|
def all_tags_list_on(tag_definition)
|
79
|
-
|
80
|
-
cached_variable = instance_variable_get(variable_name)
|
81
|
-
|
82
|
-
return cached_variable if instance_variable_defined?(variable_name) && cached_variable
|
83
|
-
|
84
|
-
instance_variable_set(variable_name, ActsAsTaggableOnMongoid::TagList.new(tag_definition, all_tags_on(tag_definition).map(&:name)).freeze)
|
175
|
+
tag_list_cache_on(tag_definition).flatten
|
85
176
|
end
|
86
177
|
|
87
178
|
##
|
88
179
|
# Returns all tags of a given context
|
89
180
|
def all_tags_on(tag_definition)
|
90
|
-
tag_definition.
|
181
|
+
scope = public_send(tag_definition.taggings_name).where(context: tag_definition.tag_type)
|
182
|
+
|
183
|
+
# when preserving tag order, return tags in created order
|
184
|
+
# if we added the order to the association this would always apply
|
185
|
+
scope = scope.order_by(*tag_definition.taggings_order) if tag_definition.preserve_tag_order?
|
186
|
+
|
187
|
+
scope
|
91
188
|
end
|
92
189
|
|
93
190
|
##
|
94
191
|
# Returns all tags that are not owned of a given context
|
95
192
|
def tags_on(tag_definition)
|
96
|
-
|
97
|
-
|
193
|
+
scope = public_send(tag_definition.taggings_name).where(context: tag_definition.tag_type, :tagger_id.exists => false)
|
194
|
+
|
195
|
+
# when preserving tag order, return tags in created order
|
196
|
+
# if we added the order to the association this would always apply
|
197
|
+
scope = scope.order_by(*tag_definition.taggings_order) if tag_definition.preserve_tag_order?
|
198
|
+
|
199
|
+
scope
|
200
|
+
end
|
201
|
+
|
202
|
+
##
|
203
|
+
# Returns all tags that are owned by a given tagger of a given context
|
204
|
+
def tagger_tags_on(tagger, tag_definition)
|
205
|
+
scope = public_send(tag_definition.taggings_name).where(context: tag_definition.tag_type, tagger: tagger)
|
98
206
|
|
99
207
|
# when preserving tag order, return tags in created order
|
100
208
|
# if we added the order to the association this would always apply
|
@@ -105,41 +213,56 @@ module ActsAsTaggableOnMongoid
|
|
105
213
|
|
106
214
|
def mark_tag_list_changed(new_list)
|
107
215
|
tag_definition = new_list.tag_definition
|
108
|
-
current_tag_list =
|
216
|
+
current_tag_list = tag_list_cache_on(tag_definition)
|
109
217
|
|
110
|
-
if
|
111
|
-
|
112
|
-
|
113
|
-
|
218
|
+
return if current_tag_list == new_list
|
219
|
+
|
220
|
+
current_tag_list.notify_will_change
|
221
|
+
end
|
222
|
+
|
223
|
+
def tagger_tag_list_set(new_list)
|
224
|
+
instance_variable_set(new_list.tag_definition.tag_list_variable_name, new_list)
|
114
225
|
end
|
115
226
|
|
116
227
|
def tag_list_set(new_list)
|
117
228
|
# add_custom_context(tag_definition, owner)
|
118
229
|
|
119
230
|
new_list.taggable = self
|
231
|
+
tag_definition = new_list.tag_definition
|
232
|
+
tagger_tag_list = ActsAsTaggableOnMongoid::TaggerTagList.new(tag_definition, self)
|
120
233
|
|
121
|
-
|
234
|
+
tagger_tag_list[new_list.tagger] = new_list
|
235
|
+
|
236
|
+
instance_variable_set(tag_definition.tag_list_variable_name, tagger_tag_list)
|
122
237
|
end
|
123
238
|
|
124
239
|
##
|
125
240
|
# Find existing tags or create non-existing tags
|
126
|
-
def load_tags(tag_definition,
|
127
|
-
tag_definition.tags_table.
|
241
|
+
def load_tags(tag_definition, tagger_tag_list)
|
242
|
+
tag_definition.tags_table.find_or_create_tagger_list_with_like_by_name(tag_definition, tagger_tag_list)
|
128
243
|
end
|
129
244
|
|
130
245
|
def set_tag_list_defaults
|
131
|
-
return unless new_record?
|
246
|
+
return [] unless new_record?
|
132
247
|
|
248
|
+
defaulted_values = []
|
133
249
|
tag_types.each_value do |tag_definition|
|
134
|
-
|
250
|
+
next if instance_variable_defined?(tag_definition.tag_list_variable_name)
|
251
|
+
|
252
|
+
default = tag_definition.taggable_default(self)
|
135
253
|
next unless default.present?
|
136
254
|
|
137
|
-
|
138
|
-
next if public_send(tag_list_name).present?
|
255
|
+
set_default_value(tag_definition, default)
|
139
256
|
|
140
|
-
|
141
|
-
changed_attributes.delete tag_list_name
|
257
|
+
defaulted_values << tag_definition.tag_list_name
|
142
258
|
end
|
259
|
+
|
260
|
+
defaulted_values
|
261
|
+
end
|
262
|
+
|
263
|
+
def set_default_value(tag_definition, default)
|
264
|
+
public_send(tag_definition.tagger_tag_lists_name)[default.tagger] = default
|
265
|
+
changed_attributes.delete tag_definition.tag_list_name
|
143
266
|
end
|
144
267
|
|
145
268
|
def save_tags
|
@@ -167,11 +290,11 @@ module ActsAsTaggableOnMongoid
|
|
167
290
|
end
|
168
291
|
|
169
292
|
def extract_tag_list_changes(tag_definition)
|
170
|
-
tag_list = tag_list_cache_on(tag_definition)
|
293
|
+
tag_list = tag_list_cache_on(tag_definition)
|
171
294
|
|
172
295
|
# Find existing tags or create non-existing tags:
|
173
296
|
tags = find_or_create_tags_from_list_with_context(tag_definition, tag_list)
|
174
|
-
current_tags =
|
297
|
+
current_tags = all_tags_on(tag_definition)
|
175
298
|
|
176
299
|
tag_list_diff = ActsAsTaggableOnMongoid::Taggable::Utils::TagListDiff.new tag_definition: tag_definition,
|
177
300
|
tags: tags,
|
@@ -210,10 +333,10 @@ module ActsAsTaggableOnMongoid
|
|
210
333
|
# end
|
211
334
|
# end
|
212
335
|
#
|
213
|
-
# @param [Array<String>]
|
214
|
-
# @param [Symbol]
|
215
|
-
def find_or_create_tags_from_list_with_context(tag_definition,
|
216
|
-
load_tags(tag_definition,
|
336
|
+
# @param [Array<String>] tagger_tag_list Tags to find or create grouped by tagger
|
337
|
+
# @param [Symbol] tag_definition The tag context for the tag_list
|
338
|
+
def find_or_create_tags_from_list_with_context(tag_definition, tagger_tag_list)
|
339
|
+
load_tags(tag_definition, tagger_tag_list)
|
217
340
|
end
|
218
341
|
end
|
219
342
|
end
|