mongoid_taggable_with_context 1.1.0 → 1.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 +4 -4
- data/.travis.yml +4 -5
- data/Gemfile +0 -5
- data/README.md +9 -2
- data/lib/mongoid/taggable_with_context.rb +205 -57
- data/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb +12 -12
- data/lib/mongoid/taggable_with_context/deprecations.rb +26 -0
- data/lib/mongoid/taggable_with_context/version.rb +1 -1
- data/lib/mongoid_taggable_with_context.rb +2 -2
- data/mongoid_taggable_with_context.gemspec +8 -3
- data/spec/mongoid_taggable_with_context_spec.rb +18 -1
- data/spec/spec_helper.rb +1 -6
- metadata +2 -3
- data/lib/mongoid/taggable_with_context/group_by/aggregation_strategy/real_time.rb +0 -53
- data/lib/mongoid/taggable_with_context/group_by/taggable_with_context.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bf82479160ee3dcffed85dfc206a3c13278cbc3
|
4
|
+
data.tar.gz: aa4b64c413c645d566f58626bda4741e3be5e0a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb4fb9bc4478bc6cee3c68dedbe18714ab07561395238386398b802d5c2ca62edb364b53f99f01e7e38cce123eea2a21e99a6cbe91ca2a570f9c0795d0432054
|
7
|
+
data.tar.gz: 44c396f2e5f22b7de4ebae7706a67fbcd7499691e61c809e190d594e54e97ee10d175696f6c18830d1fff57aec850f4e791d357e546ae49dc858c08f95679ef7
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -2,12 +2,7 @@ source 'http://rubygems.org'
|
|
2
2
|
|
3
3
|
gem 'mongoid', '>= 3.0.0'
|
4
4
|
|
5
|
-
# Add dependencies to develop your gem here.
|
6
|
-
# Include everything needed to run rake, tests, features, etc.
|
7
5
|
group :development do
|
8
|
-
gem 'database_cleaner'
|
9
|
-
#gem 'bson'
|
10
|
-
#gem 'bson_ext'
|
11
6
|
gem 'rspec'
|
12
7
|
gem 'yard'
|
13
8
|
gem 'bundler', '>= 1.0.0'
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@ mongoid_taggable_with_context
|
|
2
2
|
=============================
|
3
3
|
|
4
4
|
[](http://travis-ci.org/lgs/mongoid_taggable_with_context) [](https://gemnasium.com/lgs/mongoid_taggable_with_context)
|
5
|
+
[](https://codeclimate.com/github/lgs/mongoid_taggable_with_context)
|
5
6
|
|
6
7
|
A tagging lib for Mongoid that allows for custom tagging along dynamic contexts. This gem was originally based on [mongoid_taggable](https://github.com/ches/mongoid_taggable) by Wilker Lúcio and Ches Martin. It has evolved substantially since that point, but all credit goes to them for the initial tagging functionality.
|
7
8
|
|
@@ -61,6 +62,11 @@ Example:
|
|
61
62
|
The delimiter used when converting the tags to and from String format. Defaults to " "
|
62
63
|
|
63
64
|
|
65
|
+
* `@option [ :Symbol ] :group_by_field`
|
66
|
+
|
67
|
+
The Mongoid field to group by when RealTimeGroupBy aggregation is used.
|
68
|
+
|
69
|
+
|
64
70
|
* `@option [ <various> ] :default, :as, :localize, etc.`
|
65
71
|
|
66
72
|
Options for Mongoid #field method will be automatically passed
|
@@ -83,11 +89,11 @@ class Post
|
|
83
89
|
field :content
|
84
90
|
|
85
91
|
# default context is 'tags'.
|
86
|
-
# This creates #tags, #tags=, #
|
92
|
+
# This creates #tags, #tags=, #tag_string instance methods
|
87
93
|
# separator is " " by default
|
88
94
|
# #tags method returns an array of tags
|
89
95
|
# #tags= methods accepts an array of tags or a separated string
|
90
|
-
# #
|
96
|
+
# #tag_string method returns a separated string
|
91
97
|
taggable
|
92
98
|
|
93
99
|
# tagging for 'skills' context.
|
@@ -141,6 +147,7 @@ This lib presents the following aggregation strategies:
|
|
141
147
|
|
142
148
|
* MapReduce
|
143
149
|
* RealTime
|
150
|
+
* RealTimeGroupBy
|
144
151
|
|
145
152
|
The following document will automatically aggregate counts on all tag contexts.
|
146
153
|
|
@@ -12,7 +12,7 @@ module Mongoid::TaggableWithContext
|
|
12
12
|
self.taggable_with_context_options = {}
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def tag_string_for(context)
|
16
16
|
self.read_attribute(context).join(self.class.get_tag_separator_for(context))
|
17
17
|
end
|
18
18
|
|
@@ -28,69 +28,26 @@ module Mongoid::TaggableWithContext
|
|
28
28
|
# taggable :keywords, separator: ' ', default: ['foobar']
|
29
29
|
# end
|
30
30
|
#
|
31
|
-
# @param [ Symbol ] field The name of the field for tags.
|
31
|
+
# @param [ Symbol ] field The name of the field for tags. Defaults to :tags if not specified.
|
32
32
|
# @param [ Hash ] options Options for taggable behavior.
|
33
33
|
#
|
34
34
|
# @option options [ String ] :separator
|
35
35
|
# The delimiter used when converting the tags to and from String format. Defaults to ' '
|
36
|
+
# @option options [ :Symbol ] :group_by_field
|
37
|
+
# The Mongoid field to group by when RealTimeGroupBy aggregation is used.
|
36
38
|
# @option options [ <various> ] :default, :as, :localize, etc.
|
37
39
|
# Options for Mongoid #field method will be automatically passed
|
38
40
|
# to the underlying Array field
|
39
41
|
def taggable(*args)
|
40
42
|
# init variables
|
41
43
|
options = args.extract_options!
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
# field: the field name used to identify the tags. :field will
|
50
|
-
# be identical to :db_field unless the :as option is specified
|
51
|
-
options[:field] = options[:as] || options[:db_field]
|
52
|
-
|
53
|
-
options.reverse_merge!(separator: DEFAULT_SEPARATOR)
|
54
|
-
|
55
|
-
# register / update settings
|
56
|
-
self.taggable_with_context_options[options[:field]] = options
|
57
|
-
|
58
|
-
# setup fields & indexes
|
59
|
-
field options[:db_field], mongoid_field_options(options)
|
60
|
-
|
61
|
-
index({ options[:field] => 1 }, { background: true })
|
62
|
-
|
63
|
-
# singleton methods
|
64
|
-
self.class.class_eval do
|
65
|
-
# retrieve all tags ever created for the model
|
66
|
-
define_method options[:field] do
|
67
|
-
tags_for(options[:field])
|
68
|
-
end
|
69
|
-
|
70
|
-
# retrieve all tags ever created for the model with weights
|
71
|
-
define_method :"#{options[:field]}_with_weight" do
|
72
|
-
tags_with_weight_for(options[:field])
|
73
|
-
end
|
74
|
-
|
75
|
-
define_method :"#{options[:field]}_separator" do
|
76
|
-
get_tag_separator_for(options[:field])
|
77
|
-
end
|
78
|
-
|
79
|
-
define_method :"#{options[:field]}_tagged_with" do |tags|
|
80
|
-
tagged_with(options[:field], tags)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
#instance methods
|
85
|
-
class_eval do
|
86
|
-
define_method :"#{options[:field]}_string" do
|
87
|
-
tags_string_for(options[:field])
|
88
|
-
end
|
89
|
-
|
90
|
-
define_method :"#{options[:field]}=" do |value|
|
91
|
-
write_attribute(options[:field], self.class.format_tags_for(options[:field], value))
|
92
|
-
end
|
93
|
-
end
|
44
|
+
field = args.present? ? args.shift.to_sym : DEFAULT_FIELD
|
45
|
+
added = add_taggable(field, options)
|
46
|
+
# TODO: test if this is needed
|
47
|
+
# descendants.each do |subclass|
|
48
|
+
# subclass.add_taggable(field, options)
|
49
|
+
# end
|
50
|
+
added
|
94
51
|
end
|
95
52
|
|
96
53
|
def tag_contexts
|
@@ -107,11 +64,11 @@ module Mongoid::TaggableWithContext
|
|
107
64
|
self.taggable_with_context_options[context]
|
108
65
|
end
|
109
66
|
|
110
|
-
def tags_for(context, conditions={})
|
67
|
+
def tags_for(context, group_by=nil, conditions={})
|
111
68
|
raise AggregationStrategyMissing
|
112
69
|
end
|
113
70
|
|
114
|
-
def tags_with_weight_for(context, conditions={})
|
71
|
+
def tags_with_weight_for(context, group_by=nil, conditions={})
|
115
72
|
raise AggregationStrategyMissing
|
116
73
|
end
|
117
74
|
|
@@ -119,6 +76,9 @@ module Mongoid::TaggableWithContext
|
|
119
76
|
self.taggable_with_context_options[context][:separator]
|
120
77
|
end
|
121
78
|
|
79
|
+
def get_tag_group_by_field_for(context)
|
80
|
+
self.taggable_with_context_options[context][:group_by_field]
|
81
|
+
end
|
122
82
|
|
123
83
|
# Find documents tagged with all tags passed as a parameter, given
|
124
84
|
# as an Array or a String using the configured separator.
|
@@ -153,11 +113,199 @@ module Mongoid::TaggableWithContext
|
|
153
113
|
|
154
114
|
protected
|
155
115
|
|
156
|
-
#
|
116
|
+
# Adds a taggable context to the list of contexts, and creates the underlying
|
117
|
+
# Mongoid field and alias methods for the context.
|
118
|
+
#
|
119
|
+
# @param [ Symbol ] field The name of the Mongoid database field to store the taggable.
|
120
|
+
# @param [ Hash ] options The taggable options.
|
121
|
+
#
|
122
|
+
# @since 1.1.1
|
123
|
+
def add_taggable(field, options)
|
124
|
+
validate_taggable_options(options)
|
125
|
+
|
126
|
+
# db_field: the field name stored in the database
|
127
|
+
options[:db_field] = field.to_sym
|
128
|
+
# field: the field name used to identify the tags. :field will
|
129
|
+
# be identical to :db_field unless the :as option is specified
|
130
|
+
options[:field] = options[:as] || field
|
131
|
+
context = options[:field]
|
132
|
+
options.reverse_merge!(
|
133
|
+
separator: DEFAULT_SEPARATOR
|
134
|
+
)
|
135
|
+
|
136
|
+
# register / update settings
|
137
|
+
self.taggable_with_context_options[options[:field]] = options
|
138
|
+
|
139
|
+
create_taggable_mongoid_field(field, options)
|
140
|
+
create_taggable_mongoid_index(context)
|
141
|
+
define_taggable_accessors(context)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Validates the taggable options and raises errors if invalid options are detected.
|
145
|
+
#
|
146
|
+
# @param [ Hash ] options The taggable options.
|
147
|
+
#
|
148
|
+
# @since 1.1.1
|
149
|
+
def validate_taggable_options(options)
|
150
|
+
if options[:field]
|
151
|
+
raise <<-ERR
|
152
|
+
taggable :field option has been removed as of version 1.1.1. Please use the
|
153
|
+
syntax "taggable <database_name>, as: <tag_name>"
|
154
|
+
ERR
|
155
|
+
end
|
156
|
+
if options[:string_method]
|
157
|
+
raise <<-ERR
|
158
|
+
taggable :string_method option has been removed as of version 1.1.1. Please
|
159
|
+
define an alias to "<tags>_string" in your Model
|
160
|
+
ERR
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Creates the underlying Mongoid field for the tag context.
|
165
|
+
#
|
166
|
+
# @param [ Symbol ] name The name of the Mongoid field.
|
167
|
+
# @param [ Hash ] options Options for the Mongoid field.
|
168
|
+
#
|
169
|
+
# @since 1.1.1
|
170
|
+
def create_taggable_mongoid_field(name, options)
|
171
|
+
field name, mongoid_field_options(options)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Prepares valid Mongoid option keys from the taggable options. Slices
|
175
|
+
# the taggable options to include only valid options for the Mongoid #field
|
176
|
+
# method, and coerces :type to Array.
|
177
|
+
#
|
157
178
|
# @param [ Hash ] :options The taggable options hash.
|
158
179
|
# @return [ Hash ] A options hash for the Mongoid #field method.
|
180
|
+
#
|
181
|
+
# @since 1.1.1
|
159
182
|
def mongoid_field_options(options = {})
|
160
183
|
options.slice(*::Mongoid::Fields::Validators::Macro::OPTIONS).merge!(type: Array)
|
161
184
|
end
|
185
|
+
|
186
|
+
# Creates an index for the underlying Mongoid field.
|
187
|
+
#
|
188
|
+
# @param [ Symbol ] name The name or alias name of Mongoid field.
|
189
|
+
#
|
190
|
+
# @since 1.1.1
|
191
|
+
def create_taggable_mongoid_index(name)
|
192
|
+
index({ name => 1 }, { background: true })
|
193
|
+
end
|
194
|
+
|
195
|
+
# Defines all accessor methods for the taggable context at both
|
196
|
+
# the instance and class level.
|
197
|
+
#
|
198
|
+
# @param [ Symbol ] context The name of the tag context.
|
199
|
+
#
|
200
|
+
# @since 1.1.1
|
201
|
+
def define_taggable_accessors(context)
|
202
|
+
define_class_tags_getter(context)
|
203
|
+
define_class_weighted_tags_getter(context)
|
204
|
+
define_class_separator_getter(context)
|
205
|
+
define_class_tagged_with_getter(context)
|
206
|
+
define_class_group_by_getter(context)
|
207
|
+
define_instance_tag_string_getter(context)
|
208
|
+
define_instance_tag_setter(context)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Create the singleton getter method to retrieve all tags
|
212
|
+
# of a given context for all instances of the model.
|
213
|
+
#
|
214
|
+
# @param [ Symbol ] context The name of the tag context.
|
215
|
+
#
|
216
|
+
# @since 1.1.1
|
217
|
+
def define_class_tags_getter(context)
|
218
|
+
# retrieve all tags ever created for the model
|
219
|
+
self.class.class_eval do
|
220
|
+
define_method context do |group_by = nil|
|
221
|
+
tags_for(context, group_by)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Create the singleton getter method to retrieve a weighted
|
227
|
+
# array of tags of a given context for all instances of the model.
|
228
|
+
#
|
229
|
+
# @param [ Symbol ] context The name of the tag context.
|
230
|
+
#
|
231
|
+
# @since 1.1.1
|
232
|
+
def define_class_weighted_tags_getter(context)
|
233
|
+
self.class.class_eval do
|
234
|
+
define_method :"#{context}_with_weight" do |group_by = nil|
|
235
|
+
tags_with_weight_for(context, group_by)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Create the singleton getter method to retrieve the tag separator
|
241
|
+
# for a given context for all instances of the model.
|
242
|
+
#
|
243
|
+
# @param [ Symbol ] context The name of the tag context.
|
244
|
+
#
|
245
|
+
# @since 1.1.1
|
246
|
+
def define_class_separator_getter(context)
|
247
|
+
self.class.class_eval do
|
248
|
+
define_method :"#{context}_separator" do
|
249
|
+
get_tag_separator_for(context)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# Create the singleton getter method to retrieve the all
|
255
|
+
# instances of the model which contain the tag/tags for a given context.
|
256
|
+
#
|
257
|
+
# @param [ Symbol ] context The name of the tag context.
|
258
|
+
#
|
259
|
+
# @since 1.1.1
|
260
|
+
def define_class_tagged_with_getter(context)
|
261
|
+
self.class.class_eval do
|
262
|
+
define_method :"#{context}_tagged_with" do |tags|
|
263
|
+
tagged_with(context, tags)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# Create the singleton getter method to retrieve the
|
269
|
+
# group_by field
|
270
|
+
#
|
271
|
+
# @param [ Symbol ] context The name of the tag context.
|
272
|
+
#
|
273
|
+
# @since 1.1.1
|
274
|
+
def define_class_group_by_getter(context)
|
275
|
+
self.class.class_eval do
|
276
|
+
define_method :"#{context}_group_by_field" do
|
277
|
+
get_tag_group_by_field_for(context)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
# Create the setter method for the provided taggable, using an
|
283
|
+
# alias method chain to the underlying field method.
|
284
|
+
#
|
285
|
+
# @param [ Symbol ] context The name of the tag context.
|
286
|
+
#
|
287
|
+
# @since 1.1.1
|
288
|
+
def define_instance_tag_setter(context)
|
289
|
+
generated_methods.module_eval do
|
290
|
+
re_define_method("#{context}_with_taggable=") do |value|
|
291
|
+
value = self.class.format_tags_for(context, value)
|
292
|
+
self.send("#{context}_without_taggable=", value)
|
293
|
+
end
|
294
|
+
alias_method_chain "#{context}=", :taggable
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Create the getter method for the joined tags string.
|
299
|
+
#
|
300
|
+
# @param [ Symbol ] context The name of the tag context.
|
301
|
+
#
|
302
|
+
# @since 1.1.1
|
303
|
+
def define_instance_tag_string_getter(context)
|
304
|
+
generated_methods.module_eval do
|
305
|
+
re_define_method("#{context}_string") do
|
306
|
+
tag_string_for(context)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
162
310
|
end
|
163
311
|
end
|
@@ -39,25 +39,25 @@ module Mongoid::TaggableWithContext::AggregationStrategy
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def recalculate_tag_weights!(context)
|
42
|
-
|
42
|
+
db_field = self.class.tag_options_for(context)[:db_field]
|
43
43
|
|
44
44
|
map = <<-END
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
function() {
|
46
|
+
if (!this.#{db_field})return;
|
47
|
+
for (index in this.#{db_field})
|
48
|
+
emit(this.#{db_field}[index], 1);
|
49
|
+
}
|
50
50
|
END
|
51
51
|
|
52
52
|
reduce = <<-END
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
function(key, values) {
|
54
|
+
var count = 0;
|
55
|
+
for (index in values) count += values[index];
|
56
|
+
return count;
|
57
|
+
}
|
58
58
|
END
|
59
59
|
|
60
|
-
self.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
|
60
|
+
self.class.map_reduce(map, reduce).out(replace: aggregation_collection_for(context)).time
|
61
61
|
end
|
62
62
|
|
63
63
|
# adapted from https://github.com/jesuisbonbon/mongoid_taggable/commit/42feddd24dedd66b2b6776f9694d1b5b8bf6903d
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mongoid::TaggableWithContext::GroupBy
|
2
|
+
module TaggableWithContext
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
raise <<-ERR
|
6
|
+
Mongoid::TaggableWithContext::GroupBy::TaggableWithContext is no longer used.
|
7
|
+
Instead, please include both Mongoid::TaggableWithContext and
|
8
|
+
Mongoid::TaggableWithContext::AggregationStrategy::RealTimeGroupBy
|
9
|
+
in your Model.
|
10
|
+
ERR
|
11
|
+
end
|
12
|
+
end
|
13
|
+
module AggregationStrategy
|
14
|
+
module RealTime
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
included do
|
17
|
+
raise <<-ERR
|
18
|
+
Mongoid::TaggableWithContext::GroupBy::AggregationStrategy::RealTime
|
19
|
+
is no longer used. Instead, please include both Mongoid::TaggableWithContext and
|
20
|
+
Mongoid::TaggableWithContext::AggregationStrategy::RealTimeGroupBy
|
21
|
+
in your Model.
|
22
|
+
ERR
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,6 +3,6 @@ require 'active_support/concern'
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context')
|
4
4
|
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/aggregation_strategy/map_reduce')
|
5
5
|
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/aggregation_strategy/real_time')
|
6
|
-
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/
|
7
|
-
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/
|
6
|
+
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/aggregation_strategy/real_time_group_by')
|
7
|
+
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/deprecations')
|
8
8
|
require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/version')
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "mongoid_taggable_with_context"
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Aaron Qian", "Luca G. Soave", "John Shields", "Wilker Lucio", "Ches Martin"]
|
@@ -26,8 +26,13 @@ Gem::Specification.new do |s|
|
|
26
26
|
"lib/mongoid/taggable_with_context.rb",
|
27
27
|
"lib/mongoid/taggable_with_context/aggregation_strategy/map_reduce.rb",
|
28
28
|
"lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb",
|
29
|
-
|
30
|
-
|
29
|
+
# fix Gem::InvalidSpecificationException, commenting group_by dir
|
30
|
+
# and by adding lib/mongoid/taggable_with_context/deprecations.rb
|
31
|
+
#
|
32
|
+
#"lib/mongoid/taggable_with_context/group_by/aggregation_strategy/real_time.rb",
|
33
|
+
#"lib/mongoid/taggable_with_context/group_by/taggable_with_context.rb",
|
34
|
+
#
|
35
|
+
"lib/mongoid/taggable_with_context/deprecations.rb",
|
31
36
|
"lib/mongoid/taggable_with_context/version.rb",
|
32
37
|
"lib/mongoid_taggable_with_context.rb",
|
33
38
|
"mongoid_taggable_with_context.gemspec",
|
@@ -29,7 +29,8 @@ end
|
|
29
29
|
|
30
30
|
class M3
|
31
31
|
include Mongoid::Document
|
32
|
-
include Mongoid::TaggableWithContext
|
32
|
+
include Mongoid::TaggableWithContext
|
33
|
+
include Mongoid::TaggableWithContext::AggregationStrategy::RealTimeGroupBy
|
33
34
|
|
34
35
|
field :user
|
35
36
|
taggable group_by_field: :user
|
@@ -433,5 +434,21 @@ describe Mongoid::TaggableWithContext do
|
|
433
434
|
end
|
434
435
|
end.to raise_error
|
435
436
|
end
|
437
|
+
it "should throw error if GroupBy::TaggableWithContext module is included" do
|
438
|
+
expect do
|
439
|
+
class Invalid
|
440
|
+
include Mongoid::Document
|
441
|
+
include Mongoid::TaggableWithContext::GroupBy::TaggableWithContext
|
442
|
+
end
|
443
|
+
end.to raise_error
|
444
|
+
end
|
445
|
+
it "should throw error if GroupBy::AggregationStrategy::RealTime module is included" do
|
446
|
+
expect do
|
447
|
+
class Invalid
|
448
|
+
include Mongoid::Document
|
449
|
+
include Mongoid::TaggableWithContext::GroupBy::AggregationStrategy::RealTime
|
450
|
+
end
|
451
|
+
end.to raise_error
|
452
|
+
end
|
436
453
|
end
|
437
454
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,15 +4,10 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
4
4
|
require 'rspec'
|
5
5
|
require 'mongoid'
|
6
6
|
require 'mongoid_taggable_with_context.rb'
|
7
|
-
require 'database_cleaner'
|
8
7
|
|
9
8
|
RSpec.configure do |config|
|
10
|
-
config.before(:suite) do
|
11
|
-
DatabaseCleaner.strategy = :truncation
|
12
|
-
end
|
13
|
-
|
14
9
|
config.after(:each) do
|
15
|
-
|
10
|
+
Mongoid.purge!
|
16
11
|
end
|
17
12
|
end
|
18
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_taggable_with_context
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Qian
|
@@ -116,8 +116,7 @@ files:
|
|
116
116
|
- lib/mongoid/taggable_with_context.rb
|
117
117
|
- lib/mongoid/taggable_with_context/aggregation_strategy/map_reduce.rb
|
118
118
|
- lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb
|
119
|
-
- lib/mongoid/taggable_with_context/
|
120
|
-
- lib/mongoid/taggable_with_context/group_by/taggable_with_context.rb
|
119
|
+
- lib/mongoid/taggable_with_context/deprecations.rb
|
121
120
|
- lib/mongoid/taggable_with_context/version.rb
|
122
121
|
- lib/mongoid_taggable_with_context.rb
|
123
122
|
- mongoid_taggable_with_context.gemspec
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Mongoid::TaggableWithContext::GroupBy::AggregationStrategy
|
2
|
-
module RealTime
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
include Mongoid::TaggableWithContext::GroupBy::TaggableWithContext
|
5
|
-
include Mongoid::TaggableWithContext::AggregationStrategy::RealTime
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
def tag_name_attribute
|
9
|
-
"_name"
|
10
|
-
end
|
11
|
-
|
12
|
-
def tags_for(context, group_by, conditions={})
|
13
|
-
results = if group_by
|
14
|
-
query(context, group_by).to_a.map{ |t| t[tag_name_attribute] }
|
15
|
-
else
|
16
|
-
super(context, conditions)
|
17
|
-
end
|
18
|
-
results.uniq
|
19
|
-
end
|
20
|
-
|
21
|
-
def tags_with_weight_for(context, group_by, conditions={})
|
22
|
-
results = if group_by
|
23
|
-
query(context, group_by).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
|
24
|
-
else
|
25
|
-
super(context, conditions)
|
26
|
-
end
|
27
|
-
|
28
|
-
tag_hash = {}
|
29
|
-
results.each do |tag, weight|
|
30
|
-
tag_hash[tag] ||= 0
|
31
|
-
tag_hash[tag] += weight
|
32
|
-
end
|
33
|
-
tag_hash.to_a
|
34
|
-
end
|
35
|
-
|
36
|
-
protected
|
37
|
-
def query(context, group_by)
|
38
|
-
aggregation_database_collection_for(context).find({value: {"$gt" => 0 }, group_by_field: group_by}).sort(tag_name_attribute.to_sym => 1)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
|
44
|
-
def get_conditions(context, tag)
|
45
|
-
conditions = {self.class.tag_name_attribute.to_sym => tag}
|
46
|
-
group_by_field = self.class.get_tag_group_by_field_for(context)
|
47
|
-
if group_by_field
|
48
|
-
conditions.merge!({group_by_field: self.send(group_by_field)})
|
49
|
-
end
|
50
|
-
conditions
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Mongoid::TaggableWithContext::GroupBy
|
2
|
-
module TaggableWithContext
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
include Mongoid::TaggableWithContext
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def taggable(*args)
|
8
|
-
super(*args)
|
9
|
-
args.extract_options!
|
10
|
-
tags_field = args.present? ? args.shift.to_sym : :tags
|
11
|
-
self.taggable_with_context_options[tags_field].reverse_merge!(group_by_field: nil)
|
12
|
-
|
13
|
-
# singleton methods
|
14
|
-
self.class.class_eval do
|
15
|
-
define_method tags_field do |group_by = nil|
|
16
|
-
tags_for(tags_field, group_by)
|
17
|
-
end
|
18
|
-
|
19
|
-
define_method :"#{tags_field}_with_weight" do |group_by = nil|
|
20
|
-
tags_with_weight_for(tags_field, group_by)
|
21
|
-
end
|
22
|
-
|
23
|
-
define_method :"#{tags_field}_group_by_field" do
|
24
|
-
get_tag_group_by_field_for(tags_field)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def tags_for(context, group_by, conditions={})
|
30
|
-
raise AggregationStrategyMissing
|
31
|
-
end
|
32
|
-
|
33
|
-
def tags_with_weight_for(context, group_by, conditions={})
|
34
|
-
raise AggregationStrategyMissing
|
35
|
-
end
|
36
|
-
|
37
|
-
def get_tag_group_by_field_for(context)
|
38
|
-
self.taggable_with_context_options[context][:group_by_field]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|