acts-as-taggable-on-mongoid 6.0.1.1
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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +63 -0
- data/.gitignore +54 -0
- data/.reek.yml +8 -0
- data/.rspec +2 -0
- data/.rubocop.yml +59 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +203 -0
- data/LICENSE.txt +21 -0
- data/PULL_REQUEST_TEMPLATE.md +11 -0
- data/README.md +741 -0
- data/Rakefile +8 -0
- data/acts-as-taggable-on-mongoid.gemspec +54 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/codecov.yml +3 -0
- data/config/pronto-circleci.yml +7 -0
- data/lib/acts-as-taggable-on-mongoid.rb +80 -0
- data/lib/acts_as_taggable_on_mongoid/configuration.rb +94 -0
- data/lib/acts_as_taggable_on_mongoid/default_parser.rb +120 -0
- data/lib/acts_as_taggable_on_mongoid/errors/duplicate_tag_error.rb +9 -0
- data/lib/acts_as_taggable_on_mongoid/generic_parser.rb +44 -0
- data/lib/acts_as_taggable_on_mongoid/models/tag.rb +103 -0
- data/lib/acts_as_taggable_on_mongoid/models/tagging.rb +80 -0
- data/lib/acts_as_taggable_on_mongoid/tag_list.rb +169 -0
- data/lib/acts_as_taggable_on_mongoid/taggable.rb +131 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/changeable.rb +71 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/core.rb +219 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/list_tags.rb +45 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition.rb +189 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/attributes.rb +77 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/changeable.rb +140 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/tag_type_definition/names.rb +39 -0
- data/lib/acts_as_taggable_on_mongoid/taggable/utils/tag_list_diff.rb +121 -0
- data/lib/acts_as_taggable_on_mongoid/version.rb +5 -0
- metadata +352 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsTaggableOnMongoid
|
4
|
+
module Taggable
|
5
|
+
# Overides of methods from Mongoid::Changeable
|
6
|
+
module Changeable
|
7
|
+
def tag_list_on_changed(tag_definition)
|
8
|
+
attribute_will_change!(tag_definition.tag_list_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def reload(*args)
|
12
|
+
tag_types.each_value do |tag_definition|
|
13
|
+
instance_variable_set tag_definition.all_tag_list_variable_name, nil
|
14
|
+
instance_variable_set tag_definition.tag_list_variable_name, nil
|
15
|
+
end
|
16
|
+
|
17
|
+
super(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def changed
|
21
|
+
changed_values = super
|
22
|
+
tag_list_names = tag_types.values.map(&:tag_list_name).map(&:to_s)
|
23
|
+
|
24
|
+
changed_attributes.each_key do |key|
|
25
|
+
next unless tag_list_names.include?(key.to_s)
|
26
|
+
|
27
|
+
if public_send("#{key}_changed?")
|
28
|
+
changed_values << key unless changed_values.include?(key)
|
29
|
+
else
|
30
|
+
changed_values.delete(key)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
changed_values
|
35
|
+
end
|
36
|
+
|
37
|
+
def changes
|
38
|
+
changed_values = super
|
39
|
+
|
40
|
+
tag_types.each_value do |tag_definition|
|
41
|
+
tag_list_name = tag_definition.tag_list_name
|
42
|
+
|
43
|
+
next unless changed_attributes.key? tag_list_name
|
44
|
+
|
45
|
+
changed_values[tag_list_name] = [changed_attributes[tag_list_name], public_send(tag_list_name)]
|
46
|
+
end
|
47
|
+
|
48
|
+
changed_values
|
49
|
+
end
|
50
|
+
|
51
|
+
def setters
|
52
|
+
setter_values = super
|
53
|
+
tag_list_names = tag_types.values.map(&:tag_list_name).map(&:to_s)
|
54
|
+
|
55
|
+
setter_values.delete_if do |key, _value|
|
56
|
+
tag_list_names.include?(key.to_s)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def attribute_will_change!(attribute_name)
|
63
|
+
return super if tag_types.none? { |_tag_name, tag_definition| tag_definition.tag_list_name.to_s == attribute_name.to_s }
|
64
|
+
|
65
|
+
return if changed_attributes.key?(attribute_name)
|
66
|
+
|
67
|
+
changed_attributes[attribute_name] = public_send(attribute_name)&.dup
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,219 @@
|
|
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 Core
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
|
18
|
+
DYNAMIC_MODULE_NAME = :DynamicAttributes
|
19
|
+
|
20
|
+
included do
|
21
|
+
# TODO: allow custom contexts
|
22
|
+
# attr_writer :custom_contexts
|
23
|
+
|
24
|
+
after_save :save_tags
|
25
|
+
end
|
26
|
+
|
27
|
+
class_methods do
|
28
|
+
def taggable_mixin
|
29
|
+
# https://thepugautomatic.com/2013/07/dsom/
|
30
|
+
# Provides a description of what we're doing here and why.
|
31
|
+
if const_defined?(DYNAMIC_MODULE_NAME, false)
|
32
|
+
mod = const_get(DYNAMIC_MODULE_NAME)
|
33
|
+
else
|
34
|
+
mod = const_set(DYNAMIC_MODULE_NAME, Module.new)
|
35
|
+
|
36
|
+
include mod
|
37
|
+
end
|
38
|
+
|
39
|
+
mod
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def apply_pre_processed_defaults
|
44
|
+
super
|
45
|
+
|
46
|
+
set_tag_list_defaults
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def tag_list_cache_set_on(tag_definition)
|
52
|
+
variable_name = tag_definition.tag_list_variable_name
|
53
|
+
|
54
|
+
instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def tag_list_cache_on(tag_definition)
|
58
|
+
variable_name = tag_definition.tag_list_variable_name
|
59
|
+
|
60
|
+
# if instance_variable_get(variable_name)
|
61
|
+
# instance_variable_get(variable_name)
|
62
|
+
# elsif cached_tag_list_on(tag_definition) && ensure_included_cache_methods! && self.class.caching_tag_list_on?(tag_definition)
|
63
|
+
# instance_variable_set(variable_name, tag_definition.parse(cached_tag_list_on(tag_definition)))
|
64
|
+
# else
|
65
|
+
# tag_list_set(ActsAsTaggableOnMongoid::TagList.new(tag_definition, tags_on(tag_definition).map(&:tag_name)))
|
66
|
+
# end
|
67
|
+
|
68
|
+
instance_variable_get(variable_name) ||
|
69
|
+
tag_list_set(ActsAsTaggableOnMongoid::TagList.new(tag_definition, tags_on(tag_definition).map(&:tag_name)))
|
70
|
+
end
|
71
|
+
|
72
|
+
def tag_list_on(tag_definition)
|
73
|
+
# add_custom_context(tag_definition)
|
74
|
+
|
75
|
+
tag_list_cache_on(tag_definition)
|
76
|
+
end
|
77
|
+
|
78
|
+
def all_tags_list_on(tag_definition)
|
79
|
+
variable_name = tag_definition.all_tag_list_variable_name
|
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)
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Returns all tags of a given context
|
89
|
+
def all_tags_on(tag_definition)
|
90
|
+
tag_definition.tags_table.for_tag(tag_definition).to_a
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Returns all tags that are not owned of a given context
|
95
|
+
def tags_on(tag_definition)
|
96
|
+
# scope = public_send(tag_definition.taggings_name).where(context: tag_definition.tag_type, tagger_id: nil)
|
97
|
+
scope = public_send(tag_definition.taggings_name).where(context: tag_definition.tag_type)
|
98
|
+
|
99
|
+
# when preserving tag order, return tags in created order
|
100
|
+
# if we added the order to the association this would always apply
|
101
|
+
scope = scope.order_by(*tag_definition.taggings_order) if tag_definition.preserve_tag_order?
|
102
|
+
|
103
|
+
scope
|
104
|
+
end
|
105
|
+
|
106
|
+
def mark_tag_list_changed(new_list)
|
107
|
+
tag_definition = new_list.tag_definition
|
108
|
+
current_tag_list = public_send(tag_definition.tag_list_name)
|
109
|
+
|
110
|
+
if (tag_definition.preserve_tag_order? && new_list != current_tag_list) ||
|
111
|
+
new_list.sort != current_tag_list.sort
|
112
|
+
current_tag_list.notify_will_change
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def tag_list_set(new_list)
|
117
|
+
# add_custom_context(tag_definition, owner)
|
118
|
+
|
119
|
+
new_list.taggable = self
|
120
|
+
|
121
|
+
instance_variable_set(new_list.tag_definition.tag_list_variable_name, new_list)
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Find existing tags or create non-existing tags
|
126
|
+
def load_tags(tag_definition, tag_list)
|
127
|
+
tag_definition.tags_table.find_or_create_all_with_like_by_name(tag_definition, tag_list)
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_tag_list_defaults
|
131
|
+
return unless new_record?
|
132
|
+
|
133
|
+
tag_types.each_value do |tag_definition|
|
134
|
+
default = tag_definition.default
|
135
|
+
next unless default.present?
|
136
|
+
|
137
|
+
tag_list_name = tag_definition.tag_list_name
|
138
|
+
next if public_send(tag_list_name).present?
|
139
|
+
|
140
|
+
public_send("#{tag_list_name}=", default)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def save_tags
|
145
|
+
# Don't call save_tags again if a related classes save while processing this funciton causes this object to re-save.
|
146
|
+
return if @saving_tag_list
|
147
|
+
|
148
|
+
@saving_tag_list = true
|
149
|
+
|
150
|
+
tag_types.each_value do |tag_definition|
|
151
|
+
next unless tag_list_cache_set_on(tag_definition)
|
152
|
+
|
153
|
+
# List of currently assigned tag names
|
154
|
+
tag_list_diff = extract_tag_list_changes(tag_definition)
|
155
|
+
|
156
|
+
# Destroy old taggings:
|
157
|
+
tag_list_diff.destroy_old_tags self
|
158
|
+
|
159
|
+
# Create new taggings:
|
160
|
+
tag_list_diff.create_new_tags self
|
161
|
+
end
|
162
|
+
|
163
|
+
@saving_tag_list = false
|
164
|
+
|
165
|
+
true
|
166
|
+
end
|
167
|
+
|
168
|
+
def extract_tag_list_changes(tag_definition)
|
169
|
+
tag_list = tag_list_cache_on(tag_definition).uniq
|
170
|
+
|
171
|
+
# Find existing tags or create non-existing tags:
|
172
|
+
tags = find_or_create_tags_from_list_with_context(tag_definition, tag_list)
|
173
|
+
current_tags = tags_on(tag_definition).map(&:tag).compact
|
174
|
+
|
175
|
+
tag_list_diff = ActsAsTaggableOnMongoid::Taggable::Utils::TagListDiff.new tag_definition: tag_definition,
|
176
|
+
tags: tags,
|
177
|
+
current_tags: current_tags
|
178
|
+
|
179
|
+
tag_list_diff.call
|
180
|
+
|
181
|
+
tag_list_diff
|
182
|
+
end
|
183
|
+
|
184
|
+
def dirtify_tag_list(tagging)
|
185
|
+
tag_definition = tag_types[tagging.context]
|
186
|
+
|
187
|
+
return unless tag_definition
|
188
|
+
|
189
|
+
attribute_will_change! tag_definition.tag_list_name
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Imported from `ActsAsTaggableOn`. It is simply easier to define a custom Tag class and define
|
194
|
+
# the tag to use that Tag class.
|
195
|
+
#
|
196
|
+
# Override this hook if you wish to subclass {ActsAsTaggableOn::Tag} --
|
197
|
+
# context is provided so that you may conditionally use a Tag subclass
|
198
|
+
# only for some contexts.
|
199
|
+
#
|
200
|
+
# @example Custom Tag class for one context
|
201
|
+
# class Company < ActiveRecord::Base
|
202
|
+
# acts_as_taggable_on :markets, :locations
|
203
|
+
#
|
204
|
+
# def find_or_create_tags_from_list_with_context(tag_list)
|
205
|
+
# if context.to_sym == :markets
|
206
|
+
# MarketTag.find_or_create_all_with_like_by_name(tag_list)
|
207
|
+
# else
|
208
|
+
# super
|
209
|
+
# end
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# @param [Array<String>] tag_list Tags to find or create
|
213
|
+
# @param [Symbol] context The tag context for the tag_list
|
214
|
+
def find_or_create_tags_from_list_with_context(tag_definition, tag_list)
|
215
|
+
load_tags(tag_definition, tag_list)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsTaggableOnMongoid
|
4
|
+
module Taggable
|
5
|
+
# This module adds methods for tracking tag definitions within Taggable classes
|
6
|
+
module ListTags
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
class_attribute :tag_types
|
11
|
+
|
12
|
+
self.tag_types ||= {}.with_indifferent_access
|
13
|
+
end
|
14
|
+
|
15
|
+
def tag_definition(tag_type)
|
16
|
+
return unless tag_type.present?
|
17
|
+
|
18
|
+
tag_types[tag_type] ||= ActsAsTaggableOnMongoid::Taggable::TagTypeDefinition.new(self, tag_type)
|
19
|
+
end
|
20
|
+
|
21
|
+
class_methods do
|
22
|
+
# In order to allow dynamic tags, return a default tag_definition for any missing tag_type.
|
23
|
+
# This means that any dynamic tag necessarily is created with the current defaults
|
24
|
+
def define_tag(tag_type, options = {})
|
25
|
+
return if tag_type.blank?
|
26
|
+
|
27
|
+
tag_definition = tag_types[tag_type]
|
28
|
+
|
29
|
+
return tag_definition if tag_definition
|
30
|
+
|
31
|
+
# tag_types is a class_attribute
|
32
|
+
# As such, we have to replace it each time with a new array so that inherited classes and instances
|
33
|
+
# are able to maintain separate lists if need be.
|
34
|
+
new_tag_types = {}.with_indifferent_access.merge!(self.tag_types || {})
|
35
|
+
self.tag_types = new_tag_types
|
36
|
+
tag_definition = new_tag_types[tag_type] = ActsAsTaggableOnMongoid::Taggable::TagTypeDefinition.new(self, tag_type, options)
|
37
|
+
|
38
|
+
tag_definition.define_base_relations
|
39
|
+
tag_definition.define_relations
|
40
|
+
tag_definition.add_tag_list
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsTaggableOnMongoid
|
4
|
+
module Taggable
|
5
|
+
# TagTypeDefinition represents the definition for a aingle tag_type in a model.
|
6
|
+
#
|
7
|
+
# The options passed into a tag_type defined through acts_as_taggable* method are stored in the tag definition
|
8
|
+
# which then drives the creation of the relations and methods that are added to the model.
|
9
|
+
#
|
10
|
+
# The TagTypeDefinition mirrors the Configuraiton attributes and defaults any value that isn't passed in
|
11
|
+
# to the value in the Configuration (ActsAsTaggableOnMongoid.configuration)
|
12
|
+
class TagTypeDefinition
|
13
|
+
attr_reader :owner,
|
14
|
+
:tag_type
|
15
|
+
|
16
|
+
include ActsAsTaggableOnMongoid::Taggable::TagTypeDefinition::Attributes
|
17
|
+
include ActsAsTaggableOnMongoid::Taggable::TagTypeDefinition::Names
|
18
|
+
include ActsAsTaggableOnMongoid::Taggable::TagTypeDefinition::Changeable
|
19
|
+
|
20
|
+
def initialize(owner, tag_type, options = {})
|
21
|
+
options.assert_valid_keys(:parser,
|
22
|
+
:preserve_tag_order,
|
23
|
+
:cached_in_model,
|
24
|
+
:force_lowercase,
|
25
|
+
:force_parameterize,
|
26
|
+
:remove_unused_tags,
|
27
|
+
:tags_table,
|
28
|
+
:taggings_table,
|
29
|
+
:default)
|
30
|
+
|
31
|
+
self.default_value = options.delete(:default)
|
32
|
+
|
33
|
+
options.each do |key, value|
|
34
|
+
instance_variable_set("@#{key}", value)
|
35
|
+
end
|
36
|
+
|
37
|
+
@owner = owner
|
38
|
+
@tag_type = tag_type
|
39
|
+
end
|
40
|
+
|
41
|
+
# rubocop:disable Layout/SpaceAroundOperators
|
42
|
+
# :reek:FeatureEnvy
|
43
|
+
|
44
|
+
# I've defined the parser as being required to return an array of strings.
|
45
|
+
# This parse function will take that array and make it a TagList which will then use the tag_definition
|
46
|
+
# to apply the rules to that list (like case sensitivity and parameterization, etc.) to get the final
|
47
|
+
# list.
|
48
|
+
def parse(*tag_list)
|
49
|
+
options = tag_list.extract_options!
|
50
|
+
options[:parser] ||= parser if options.key?(:parse) || options.key?(:parser)
|
51
|
+
|
52
|
+
ActsAsTaggableOnMongoid::TagList.new(self, *tag_list, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# rubocop:enable Layout/SpaceAroundOperators
|
56
|
+
|
57
|
+
def taggings_order
|
58
|
+
@taggings_order = if preserve_tag_order?
|
59
|
+
[:created_at.asc, :id.asc]
|
60
|
+
else
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def define_base_relations
|
66
|
+
tag_definition = self
|
67
|
+
|
68
|
+
add_base_tags_method
|
69
|
+
|
70
|
+
owner.class_eval do
|
71
|
+
taggings_name = tag_definition.taggings_name
|
72
|
+
|
73
|
+
break if relations[taggings_name.to_s]
|
74
|
+
|
75
|
+
has_many taggings_name,
|
76
|
+
as: :taggable,
|
77
|
+
dependent: :destroy,
|
78
|
+
class_name: tag_definition.taggings_table.name,
|
79
|
+
after_add: :dirtify_tag_list,
|
80
|
+
after_remove: :dirtify_tag_list
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Mongoid does not allow the `through` option for relations, so we de-normalize data and manually add the methods we need
|
85
|
+
# for through like functionality.
|
86
|
+
def add_base_tags_method
|
87
|
+
tag_definition = self
|
88
|
+
base_tags_method = tag_definition.base_tags_method
|
89
|
+
|
90
|
+
owner.taggable_mixin.module_eval do
|
91
|
+
break if methods.include?(base_tags_method)
|
92
|
+
|
93
|
+
define_method base_tags_method do
|
94
|
+
tag_definition.tags_table.where(taggable_type: tag_definition.owner.name)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def define_relations
|
100
|
+
# Relations cannot be added for the tags and taggings like they are in ActiveRecord because
|
101
|
+
# Mongoid does not allow for a scope like ActiveRecord does.
|
102
|
+
#
|
103
|
+
# Therefore the relation like actions will have to be defined separately ourselves. If any
|
104
|
+
# relation actions are missed, we'll just have to fix it here when we find them.
|
105
|
+
# (This is far from ideal, but it is the only way to work around the issue at this time.)
|
106
|
+
|
107
|
+
add_context_taggings_method
|
108
|
+
add_context_tags_method
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_context_taggings_method
|
112
|
+
tag_definition = self
|
113
|
+
taggings_name = tag_definition.taggings_name
|
114
|
+
|
115
|
+
owner.taggable_mixin.module_eval do
|
116
|
+
define_method "#{tag_definition.single_tag_type}_#{taggings_name}".to_sym do
|
117
|
+
public_send(taggings_name).
|
118
|
+
order_by(*tag_definition.taggings_order).
|
119
|
+
for_tag(tag_definition)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_context_tags_method
|
125
|
+
tag_definition = self
|
126
|
+
|
127
|
+
owner.taggable_mixin.module_eval do
|
128
|
+
define_method tag_definition.tag_type.to_sym do
|
129
|
+
public_send("#{tag_definition.single_tag_type}_#{tag_definition.taggings_name}").map(&:tag)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_tag_list
|
135
|
+
add_list_getter
|
136
|
+
add_list_setter
|
137
|
+
add_all_list_getter
|
138
|
+
add_list_exists
|
139
|
+
add_list_change
|
140
|
+
add_list_changed
|
141
|
+
add_changed_from_default?
|
142
|
+
add_will_change
|
143
|
+
add_get_was
|
144
|
+
add_reset_list
|
145
|
+
add_reset_to_default
|
146
|
+
end
|
147
|
+
|
148
|
+
def add_list_getter
|
149
|
+
tag_definition = self
|
150
|
+
tag_list_name = tag_definition.tag_list_name
|
151
|
+
|
152
|
+
owner.taggable_mixin.module_eval do
|
153
|
+
define_method(tag_list_name) do
|
154
|
+
tag_list_on tag_definition
|
155
|
+
end
|
156
|
+
|
157
|
+
alias_method "#{tag_list_name}_before_type_cast".to_sym, tag_list_name.to_sym
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_list_setter
|
162
|
+
tag_definition = self
|
163
|
+
|
164
|
+
owner.taggable_mixin.module_eval do
|
165
|
+
define_method("#{tag_definition.tag_list_name}=") do |new_tags|
|
166
|
+
new_tags = Array.wrap(new_tags)
|
167
|
+
options = new_tags.extract_options!
|
168
|
+
options[:parse] = true unless options.key?(:parse)
|
169
|
+
|
170
|
+
new_list = tag_definition.parse(*new_tags, options)
|
171
|
+
|
172
|
+
mark_tag_list_changed(new_list)
|
173
|
+
tag_list_set(new_list)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def add_all_list_getter
|
179
|
+
tag_definition = self
|
180
|
+
|
181
|
+
owner.taggable_mixin.module_eval do
|
182
|
+
define_method(tag_definition.all_tag_list_name) do
|
183
|
+
all_tags_list_on tag_definition
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|