acts-as-taggable-on-mongoid 6.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|