mongoid_taggable_with_context 0.8.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -3
- data/README.md +11 -12
- data/VERSION +1 -1
- data/lib/mongoid/taggable_with_context.rb +30 -32
- data/lib/mongoid/taggable_with_context/aggregation_strategy/map_reduce.rb +2 -2
- data/lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb +9 -9
- data/mongoid_taggable_with_context.gemspec +1 -1
- data/spec/mongoid_taggable_with_context_spec.rb +27 -38
- metadata +1 -1
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
mongoid_taggable_with_context
|
2
2
|
=============================
|
3
3
|
|
4
|
-
[![Build Status](https://secure.travis-ci.org/
|
4
|
+
[![Build Status](https://secure.travis-ci.org/lgs/mongoid_taggable_with_context.png?branch=master)](http://travis-ci.org/lgs/mongoid_taggable_with_context) [![Dependency Status](https://gemnasium.com/lgs/mongoid_taggable_with_context.png?travis)](https://gemnasium.com/lgs/mongoid_taggable_with_context)
|
5
5
|
|
6
6
|
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
7
|
|
@@ -42,23 +42,22 @@ class Post
|
|
42
42
|
field :content
|
43
43
|
|
44
44
|
# default context is 'tags'.
|
45
|
-
# This creates #tags, #tags=, #
|
45
|
+
# This creates #tags, #tags=, #tags_string instance methods
|
46
46
|
# separator is " " by default
|
47
|
-
# #tags method returns
|
48
|
-
# #tags= methods accepts
|
49
|
-
# #
|
50
|
-
# #tags_array= method accepts an array of tags
|
51
|
-
# #tags and #tags_array are automatically synched.
|
47
|
+
# #tags method returns an array of tags
|
48
|
+
# #tags= methods accepts an array of tags or a separated string
|
49
|
+
# #tags_string method returns a separated string
|
52
50
|
taggable
|
53
51
|
|
54
52
|
# tagging for 'interests' context.
|
55
|
-
# This creates #interests, #interests=, #
|
56
|
-
|
53
|
+
# This creates #interests, #interests=, #interests_string instance methods
|
54
|
+
# The tags will be persisted in a database field called 'interest_array'
|
55
|
+
taggable :interests, :field => :interest_array
|
57
56
|
|
58
57
|
# tagging for 'skills' context.
|
59
|
-
# This creates #skills, #skills=, #
|
58
|
+
# This creates #skills, #skills=, #my_skill_list instance methods
|
60
59
|
# changing tag separator to "," (Default is " ")
|
61
|
-
taggable :skills, :separator => ','
|
60
|
+
taggable :skills, :separator => ',', :string_method => :my_skill_list
|
62
61
|
end
|
63
62
|
```
|
64
63
|
|
@@ -118,7 +117,7 @@ class Post
|
|
118
117
|
field :content
|
119
118
|
|
120
119
|
taggable
|
121
|
-
taggable :interests
|
120
|
+
taggable :interests, :field => :interest_array
|
122
121
|
taggable :skills, :separator => ','
|
123
122
|
end
|
124
123
|
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
@@ -7,9 +7,9 @@ module Mongoid::TaggableWithContext
|
|
7
7
|
|
8
8
|
included do
|
9
9
|
class_attribute :taggable_with_context_options
|
10
|
-
class_attribute :
|
10
|
+
class_attribute :database_field_to_context_hash
|
11
11
|
self.taggable_with_context_options = {}
|
12
|
-
self.
|
12
|
+
self.database_field_to_context_hash = {}
|
13
13
|
delegate "convert_string_to_array", :to => 'self.class'
|
14
14
|
delegate "convert_array_to_string", :to => 'self.class'
|
15
15
|
delegate "clean_up_array", :to => 'self.class'
|
@@ -17,8 +17,8 @@ module Mongoid::TaggableWithContext
|
|
17
17
|
delegate "format_tags_for_write", :to => 'self.class'
|
18
18
|
delegate "tag_contexts", :to => 'self.class'
|
19
19
|
delegate "tag_options_for", :to => 'self.class'
|
20
|
-
delegate "
|
21
|
-
delegate "
|
20
|
+
delegate "tag_database_fields", :to => 'self.class'
|
21
|
+
delegate "database_field_to_context_hash", :to => 'self.class'
|
22
22
|
end
|
23
23
|
|
24
24
|
module ClassMethods
|
@@ -46,60 +46,58 @@ module Mongoid::TaggableWithContext
|
|
46
46
|
def taggable(*args)
|
47
47
|
# init variables
|
48
48
|
options = args.extract_options!
|
49
|
-
|
49
|
+
tags_name = (args.blank? ? :tags : args.shift).to_sym
|
50
50
|
options.reverse_merge!(
|
51
51
|
:separator => TAGGABLE_DEFAULT_SEPARATOR,
|
52
|
-
:
|
52
|
+
:string_method => "#{tags_name}_string".to_sym,
|
53
|
+
:field => tags_name
|
53
54
|
)
|
54
|
-
|
55
|
+
database_field = options[:field]
|
55
56
|
|
56
57
|
# register / update settings
|
57
|
-
self.taggable_with_context_options[
|
58
|
-
self.
|
58
|
+
self.taggable_with_context_options[tags_name] = options
|
59
|
+
self.database_field_to_context_hash[database_field] = tags_name
|
59
60
|
|
60
61
|
# setup fields & indexes
|
61
|
-
field
|
62
|
-
# deprecated: index tags_array_field
|
63
|
-
# Invalid index specification on Category: tags_array, {}
|
62
|
+
field tags_name, :type => Array, :default => options[:default]
|
64
63
|
|
65
|
-
index({
|
64
|
+
index({ database_field => 1 }, { background: true })
|
66
65
|
|
67
66
|
# singleton methods
|
68
67
|
class_eval <<-END
|
69
68
|
class << self
|
70
69
|
# retrieve all tags ever created for the model
|
71
|
-
def #{
|
72
|
-
tags_for(:"#{
|
70
|
+
def #{tags_name}
|
71
|
+
tags_for(:"#{tags_name}")
|
73
72
|
end
|
74
73
|
|
75
74
|
# retrieve all tags ever created for the model with weights
|
76
|
-
def #{
|
77
|
-
tags_with_weight_for(:"#{
|
75
|
+
def #{tags_name}_with_weight
|
76
|
+
tags_with_weight_for(:"#{tags_name}")
|
78
77
|
end
|
79
78
|
|
80
|
-
def #{
|
81
|
-
get_tag_separator_for(:"#{
|
79
|
+
def #{tags_name}_separator
|
80
|
+
get_tag_separator_for(:"#{tags_name}")
|
82
81
|
end
|
83
82
|
|
84
|
-
def #{
|
85
|
-
set_tag_separator_for(:"#{
|
83
|
+
def #{tags_name}_separator=(value)
|
84
|
+
set_tag_separator_for(:"#{tags_name}", value)
|
86
85
|
end
|
87
86
|
|
88
|
-
def #{
|
89
|
-
tagged_with(:"#{
|
87
|
+
def #{tags_name}_tagged_with(tags)
|
88
|
+
tagged_with(:"#{tags_name}", tags)
|
90
89
|
end
|
91
90
|
end
|
92
91
|
END
|
93
92
|
|
94
93
|
# instance methods
|
95
94
|
class_eval <<-END
|
96
|
-
def #{
|
97
|
-
convert_array_to_string(#{
|
95
|
+
def #{options[:string_method]}
|
96
|
+
convert_array_to_string(#{database_field}, get_tag_separator_for(:"#{tags_name}"))
|
98
97
|
end
|
99
|
-
def #{
|
100
|
-
write_attribute(:#{
|
98
|
+
def #{tags_name}=(value)
|
99
|
+
write_attribute(:#{database_field}, format_tags_for_write(value, get_tag_separator_for(:"#{tags_name}")))
|
101
100
|
end
|
102
|
-
alias_method :#{tags_array_field}=, :#{tags_field}=
|
103
101
|
END
|
104
102
|
end
|
105
103
|
|
@@ -107,9 +105,9 @@ module Mongoid::TaggableWithContext
|
|
107
105
|
self.taggable_with_context_options.keys
|
108
106
|
end
|
109
107
|
|
110
|
-
def
|
108
|
+
def tag_database_fields
|
111
109
|
self.taggable_with_context_options.keys.map do |context|
|
112
|
-
tag_options_for(context)[:
|
110
|
+
tag_options_for(context)[:field]
|
113
111
|
end
|
114
112
|
end
|
115
113
|
|
@@ -146,8 +144,8 @@ module Mongoid::TaggableWithContext
|
|
146
144
|
# @return [ Criteria ] A new criteria.
|
147
145
|
def tagged_with(context, tags)
|
148
146
|
tags = convert_string_to_array(tags, get_tag_separator_for(context)) if tags.is_a? String
|
149
|
-
|
150
|
-
all_in(
|
147
|
+
database_field = tag_options_for(context)[:field]
|
148
|
+
all_in(database_field => tags)
|
151
149
|
end
|
152
150
|
|
153
151
|
# Helper method to convert a a tag input value of unknown type
|
@@ -33,7 +33,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
|
|
33
33
|
protected
|
34
34
|
|
35
35
|
def changed_tag_arrays
|
36
|
-
|
36
|
+
tag_database_fields & changes.keys.map(&:to_sym)
|
37
37
|
end
|
38
38
|
|
39
39
|
def tags_changed?
|
@@ -47,7 +47,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def map_reduce_context!(context)
|
50
|
-
field = tag_options_for(context)[:
|
50
|
+
field = tag_options_for(context)[:field]
|
51
51
|
|
52
52
|
map = <<-END
|
53
53
|
function() {
|
@@ -75,8 +75,8 @@ module Mongoid::TaggableWithContext::AggregationStrategy
|
|
75
75
|
{self.class.tag_name_attribute.to_sym => tag}
|
76
76
|
end
|
77
77
|
|
78
|
-
def update_tags_aggregation(
|
79
|
-
context =
|
78
|
+
def update_tags_aggregation(database_field, old_tags=[], new_tags=[])
|
79
|
+
context = database_field_to_context_hash[database_field]
|
80
80
|
coll = self.class.aggregation_database_collection_for(context)
|
81
81
|
|
82
82
|
old_tags ||= []
|
@@ -98,19 +98,19 @@ module Mongoid::TaggableWithContext::AggregationStrategy
|
|
98
98
|
|
99
99
|
def update_tags_aggregations_on_save
|
100
100
|
indifferent_changes = HashWithIndifferentAccess.new changes
|
101
|
-
|
102
|
-
next if indifferent_changes[
|
101
|
+
tag_database_fields.each do |field|
|
102
|
+
next if indifferent_changes[field].nil?
|
103
103
|
|
104
|
-
old_tags, new_tags = indifferent_changes[
|
105
|
-
update_tags_aggregation(
|
104
|
+
old_tags, new_tags = indifferent_changes[field]
|
105
|
+
update_tags_aggregation(field, old_tags, new_tags)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
109
|
def update_tags_aggregations_on_destroy
|
110
|
-
|
111
|
-
old_tags = send
|
110
|
+
tag_database_fields.each do |field|
|
111
|
+
old_tags = send field
|
112
112
|
new_tags = []
|
113
|
-
update_tags_aggregation(
|
113
|
+
update_tags_aggregation(field, old_tags, new_tags)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
@@ -44,11 +44,11 @@ describe Mongoid::TaggableWithContext do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should be nil for artists" do
|
47
|
-
@m.
|
47
|
+
@m.artists.should eql nil
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should be array for albums" do
|
51
|
-
@m.
|
51
|
+
@m.albums.should eql []
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -57,44 +57,44 @@ describe Mongoid::TaggableWithContext do
|
|
57
57
|
@m = MyModel.new
|
58
58
|
end
|
59
59
|
|
60
|
-
it "should set tags
|
60
|
+
it "should set tags from string" do
|
61
61
|
@m.tags = "some new tag"
|
62
|
-
@m.
|
62
|
+
@m.tags.should == %w[some new tag]
|
63
63
|
end
|
64
64
|
|
65
|
-
it "should set artists
|
65
|
+
it "should set artists tags from string" do
|
66
66
|
@m.artists = "some new tag"
|
67
|
-
@m.
|
67
|
+
@m.artists.should == %w[some new tag]
|
68
68
|
end
|
69
69
|
|
70
|
-
it "should retrieve tags string
|
71
|
-
@m.
|
72
|
-
@m.
|
70
|
+
it "should retrieve tags string" do
|
71
|
+
@m.tags = %w[some new tags]
|
72
|
+
@m.tags_string.should == "some new tags"
|
73
73
|
end
|
74
74
|
|
75
|
-
it "should retrieve artists string
|
76
|
-
@m.
|
77
|
-
@m.
|
75
|
+
it "should retrieve artists string" do
|
76
|
+
@m.artists = %w[some new tags]
|
77
|
+
@m.artists_string.should == "some new tags"
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should strip tags before put in array" do
|
81
81
|
@m.tags = "now with some spaces in places "
|
82
|
-
@m.
|
82
|
+
@m.tags.should == %w[now with some spaces in places]
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should remove repeated tags from string" do
|
86
86
|
@m.tags = "some new tags some new tags"
|
87
|
-
@m.
|
87
|
+
@m.tags.should == %w[some new tags]
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should remove repeated tags from array" do
|
91
91
|
@m.tags = %w[some new tags some new tags]
|
92
|
-
@m.tags.should ==
|
92
|
+
@m.tags.should == %w[some new tags]
|
93
93
|
end
|
94
94
|
|
95
95
|
it "should remove nil tags from array" do
|
96
96
|
@m.tags = ["some", nil, "new", nil, "tags"]
|
97
|
-
@m.tags.should ==
|
97
|
+
@m.tags.should == %w[some new tags]
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -105,28 +105,17 @@ describe Mongoid::TaggableWithContext do
|
|
105
105
|
|
106
106
|
it "should remove repeated tags from array" do
|
107
107
|
@m.tags = %w[some new tags some new tags]
|
108
|
-
@m.
|
108
|
+
@m.tags.should == %w[some new tags]
|
109
109
|
end
|
110
110
|
|
111
111
|
it "should remove nil tags from array" do
|
112
112
|
@m.tags = ["some", nil, "new", nil, "tags"]
|
113
|
-
@m.
|
113
|
+
@m.tags.should == %w[some new tags]
|
114
114
|
end
|
115
115
|
|
116
116
|
it "should remove empty strings from array" do
|
117
117
|
@m.tags = ["some", "", "new", "", "tags"]
|
118
|
-
@m.
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context "saving tags from array using tags_array alias method" do
|
123
|
-
before :each do
|
124
|
-
@m = MyModel.new
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should remove nil tags from array" do
|
128
|
-
@m.tags_array = ["some", nil, "new", nil, "tags"]
|
129
|
-
@m.tags_array.should == %w[some new tags]
|
118
|
+
@m.tags.should == %w[some new tags]
|
130
119
|
end
|
131
120
|
end
|
132
121
|
|
@@ -145,12 +134,12 @@ describe Mongoid::TaggableWithContext do
|
|
145
134
|
|
146
135
|
it "should split with custom separator" do
|
147
136
|
@m.tags = "some;other;separator"
|
148
|
-
@m.
|
137
|
+
@m.tags.should == %w[some other separator]
|
149
138
|
end
|
150
139
|
|
151
|
-
it "should join with custom separator" do
|
152
|
-
@m.
|
153
|
-
@m.
|
140
|
+
it "should join string with custom separator" do
|
141
|
+
@m.tags = %w[some other sep]
|
142
|
+
@m.tags_string.should == "some;other;sep"
|
154
143
|
end
|
155
144
|
end
|
156
145
|
|
@@ -277,10 +266,10 @@ describe Mongoid::TaggableWithContext do
|
|
277
266
|
m2 = klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
|
278
267
|
m3 = klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
|
279
268
|
|
280
|
-
m1.
|
269
|
+
m1.tags = m1.tags + %w[honey strip shoe]
|
281
270
|
m1.save!
|
282
271
|
|
283
|
-
m3.
|
272
|
+
m3.artists = m3.artists + %w[grant greg gory]
|
284
273
|
m3.save!
|
285
274
|
end
|
286
275
|
|
@@ -320,10 +309,10 @@ describe Mongoid::TaggableWithContext do
|
|
320
309
|
m2 = klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
|
321
310
|
m3 = klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
|
322
311
|
|
323
|
-
m1.
|
312
|
+
m1.tags = m1.tags + %w[honey strip shoe] - %w[food]
|
324
313
|
m1.save!
|
325
314
|
|
326
|
-
m3.
|
315
|
+
m3.artists = m3.artists + %w[grant greg gory] - %w[andy]
|
327
316
|
m3.save!
|
328
317
|
|
329
318
|
m2.destroy
|