mongoid_taggable_with_context 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44ee2f3be92cc68b84183d7f2a192da8e71421c2
4
+ data.tar.gz: ec2e8f34ce303a3713d8fdda04bc1f3a61c33181
5
+ SHA512:
6
+ metadata.gz: 8b62f2358559426336e8bdc989ef7230b54483a50f128a4634afe9126325ea0f51c3de56bb940dcfc48fbeca083b21952c9652566b5d2b20a40288a19218a12f
7
+ data.tar.gz: 1ae4c6c1ff1bb80011a61275d9f9945b7564a7d2270570ee86bbf9007a457ca56d52f66ee2be7b707cfb74e3a428c3aeb82245545c3966a11b8a9fb4f8f45901
data/README.md CHANGED
@@ -28,10 +28,51 @@ or in Gemfile:
28
28
  gem 'mongoid_taggable_with_context'
29
29
  ```
30
30
 
31
- Basic Usage
32
- -----------
33
31
 
34
- To make a document taggable you need to include Mongoid::TaggableOnContext into your document and call the *taggable* macro with optional arguments:
32
+ The "taggable" Macro Function
33
+ -----------------------------
34
+
35
+ Use the `taggable` macro function in your model to
36
+ declare a tags field. Specify `field name`
37
+ for tags, and `options` for tagging behavior.
38
+
39
+ Example:
40
+
41
+ ```ruby
42
+ class Article
43
+ include Mongoid::Document
44
+ include Mongoid::TaggableWithContext
45
+ taggable :keywords, separator: ' ', default: ['foobar']
46
+ end
47
+ ```
48
+
49
+ * `@param [ Symbol ] field`
50
+
51
+ (Optional) The name of the field for tags. Defaults to "tags"
52
+
53
+
54
+ * `@param [ Hash ] options`
55
+
56
+ (Optional) Options for taggable behavior.
57
+
58
+
59
+ * `@option [ String ] :separator`
60
+
61
+ The delimiter used when converting the tags to and from String format. Defaults to " "
62
+
63
+
64
+ * `@option [ <various> ] :default, :as, :localize, etc.`
65
+
66
+ Options for Mongoid #field method will be automatically passed
67
+ to the underlying Array field (with the exception of `:type`,
68
+ which is coerced to `Array`).
69
+
70
+
71
+ Example Usage
72
+ -------------
73
+
74
+ To make a document taggable you need to include Mongoid::TaggableOnContext
75
+ into your document and call the *taggable* macro with optional arguments:
35
76
 
36
77
  ```ruby
37
78
  class Post
@@ -49,15 +90,15 @@ class Post
49
90
  # #tags_string method returns a separated string
50
91
  taggable
51
92
 
52
- # tagging for 'interests' context.
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
56
-
57
93
  # tagging for 'skills' context.
58
- # This creates #skills, #skills=, #my_skill_list instance methods
94
+ # This creates #skills, #skills=, #skills_string instance methods
59
95
  # changing tag separator to "," (Default is " ")
60
- taggable :skills, :separator => ',', :string_method => :my_skill_list
96
+ taggable :skills, separator: ','
97
+
98
+ # aliased context tagging.
99
+ # This creates #interests, #interests=, #interests_string instance methods
100
+ # The tags will be stored in a database field called 'ints'
101
+ taggable :ints, as: :interests
61
102
  end
62
103
  ```
63
104
 
@@ -91,6 +132,7 @@ Then in your form, for example:
91
132
  <% end %>
92
133
  ```
93
134
 
135
+
94
136
  Aggregation Strategies
95
137
  ----------------------
96
138
 
@@ -117,8 +159,8 @@ class Post
117
159
  field :content
118
160
 
119
161
  taggable
120
- taggable :interests, :field => :interest_array
121
- taggable :skills, :separator => ','
162
+ taggable :skills, separator: ','
163
+ taggable :ints, as: interests
122
164
  end
123
165
  ```
124
166
 
@@ -137,9 +179,9 @@ Post.skills_with_weight
137
179
  Here is how to use these methods in more detail:
138
180
 
139
181
  ```ruby
140
- Post.create!(:tags => "food,ant,bee")
141
- Post.create!(:tags => "juice,food,bee,zip")
142
- Post.create!(:tags => "honey,strip,food")
182
+ Post.create!(tags: "food,ant,bee")
183
+ Post.create!(tags: "juice,food,bee,zip")
184
+ Post.create!(tags: "honey,strip,food")
143
185
 
144
186
  Post.tags # will retrieve ["ant", "bee", "food", "honey", "juice", "strip", "zip"]
145
187
  Post.tags_with_weight # will retrieve:
@@ -154,22 +196,6 @@ Post.tags_with_weight # will retrieve:
154
196
  # ]
155
197
  ```
156
198
 
157
- Changing default separator
158
- --------------------------
159
-
160
- To change the default separator you may pass a *separator* argument to the macro:
161
-
162
- ```ruby
163
- class Post
164
- include Mongoid::Document
165
- include Mongoid::TaggableWithContext
166
-
167
- field :title
168
- field :content
169
-
170
- taggable :separator => ',' # tags will be delineated by comma instead of space
171
- end
172
- ```
173
199
 
174
200
  Contributing to mongoid_taggable_with_context
175
201
  -----------------------------------------------
@@ -182,6 +208,7 @@ Contributing to mongoid_taggable_with_context
182
208
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
183
209
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
184
210
 
211
+
185
212
  Copyright
186
213
  ---------
187
214
 
data/Rakefile CHANGED
@@ -1,23 +1,21 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
3
+ Bundler.setup
11
4
 
5
+ require 'rake'
12
6
  require 'jeweler'
7
+
8
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
9
+ require 'mongoid/taggable_with_context/version'
10
+
13
11
  Jeweler::Tasks.new do |gem|
14
12
  gem.name = "mongoid_taggable_with_context"
15
- gem.homepage = "http://github.com/aq1018/mongoid_taggable_with_context"
13
+ gem.homepage = "http://github.com/lgs/mongoid_taggable_with_context"
16
14
  gem.license = "MIT"
17
15
  gem.summary = %Q{Mongoid taggable behaviour}
18
- gem.description = %Q{It provides some helpers to create taggable documents with context.}
19
- gem.email = "aq1018@gmail.com"
20
- gem.authors = ["Aaron Qian"]
16
+ gem.description = %Q{Add multiple tag fields on Mongoid documents with aggregation capability.}
17
+ gem.authors = ["Aaron Qian", "Luca G. Soave", "John Shields", "Wilker Lucio", "Ches Martin"]
18
+ gem.version = Mongoid::TaggableWithContext::VERSION
21
19
  end
22
20
  Jeweler::RubygemsDotOrgTasks.new
23
21
 
@@ -28,7 +26,7 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
28
26
  spec.rspec_opts = "--color --format progress"
29
27
  end
30
28
 
31
- task :default => :spec
29
+ task default: :spec
32
30
 
33
31
  require 'yard'
34
32
  YARD::Rake::YardocTask.new
@@ -2,23 +2,18 @@ module Mongoid::TaggableWithContext
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  class AggregationStrategyMissing < Exception; end
5
+ class InvalidTagsFormat < Exception; end
5
6
 
6
- TAGGABLE_DEFAULT_SEPARATOR = ' '
7
+ DEFAULT_FIELD = :tags
8
+ DEFAULT_SEPARATOR = ' '
7
9
 
8
10
  included do
9
11
  class_attribute :taggable_with_context_options
10
- class_attribute :database_field_to_context_hash
11
12
  self.taggable_with_context_options = {}
12
- self.database_field_to_context_hash = {}
13
- delegate "convert_string_to_array", :to => 'self.class'
14
- delegate "convert_array_to_string", :to => 'self.class'
15
- delegate "clean_up_array", :to => 'self.class'
16
- delegate "get_tag_separator_for", :to => 'self.class'
17
- delegate "format_tags_for_write", :to => 'self.class'
18
- delegate "tag_contexts", :to => 'self.class'
19
- delegate "tag_options_for", :to => 'self.class'
20
- delegate "tag_database_fields", :to => 'self.class'
21
- delegate "database_field_to_context_hash", :to => 'self.class'
13
+ end
14
+
15
+ def tags_string_for(context)
16
+ self.read_attribute(context).join(self.class.get_tag_separator_for(context))
22
17
  end
23
18
 
24
19
  module ClassMethods
@@ -29,85 +24,82 @@ module Mongoid::TaggableWithContext
29
24
  #
30
25
  # class Article
31
26
  # include Mongoid::Document
32
- # include Mongoid::Taggable
33
- # taggable :keywords, :separator => ' ', :aggregation => true, :default_type => "seo"
27
+ # include Mongoid::TaggableWithContext
28
+ # taggable :keywords, separator: ' ', default: ['foobar']
34
29
  # end
35
30
  #
36
31
  # @param [ Symbol ] field The name of the field for tags.
37
32
  # @param [ Hash ] options Options for taggable behavior.
38
33
  #
39
- # @option options [ String ] :separator The tag separator to
40
- # convert from; defaults to ','
41
- # @option options [ true, false ] :aggregation Whether or not to
42
- # aggregate counts of tags within the document collection using
43
- # map/reduce; defaults to false
44
- # @option options [ String ] :default_type The default type of the tag.
45
- # Each tag can optionally have a tag type. The default type is nil
34
+ # @option options [ String ] :separator
35
+ # The delimiter used when converting the tags to and from String format. Defaults to ' '
36
+ # @option options [ <various> ] :default, :as, :localize, etc.
37
+ # Options for Mongoid #field method will be automatically passed
38
+ # to the underlying Array field
46
39
  def taggable(*args)
47
40
  # init variables
48
41
  options = args.extract_options!
49
- tags_name = (args.blank? ? :tags : args.shift).to_sym
50
- options.reverse_merge!(
51
- :separator => TAGGABLE_DEFAULT_SEPARATOR,
52
- :string_method => "#{tags_name}_string".to_sym,
53
- :field => tags_name
54
- )
55
- database_field = options[:field]
42
+
43
+ raise 'taggable :field option has been removed as of version 1.1.0. Please use the syntax "taggable <database_name>, as: <tag_name>"' if options[:field]
44
+ raise 'taggable :string_method option has been removed as of version 1.1.0. Please define an alias to "<tags>_string"' if options[:string_method]
45
+
46
+ # db_field: the field name stored in the database
47
+ options[:db_field] = args.present? ? args.shift.to_sym : DEFAULT_FIELD
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)
56
54
 
57
55
  # register / update settings
58
- self.taggable_with_context_options[tags_name] = options
59
- self.database_field_to_context_hash[database_field] = tags_name
56
+ self.taggable_with_context_options[options[:field]] = options
60
57
 
61
58
  # setup fields & indexes
62
- field tags_name, :type => Array, :default => options[:default]
59
+ field options[:db_field], mongoid_field_options(options)
63
60
 
64
- index({ database_field => 1 }, { background: true })
61
+ index({ options[:field] => 1 }, { background: true })
65
62
 
66
63
  # singleton methods
67
- class_eval <<-END
68
- class << self
69
- # retrieve all tags ever created for the model
70
- def #{tags_name}
71
- tags_for(:"#{tags_name}")
72
- end
73
-
74
- # retrieve all tags ever created for the model with weights
75
- def #{tags_name}_with_weight
76
- tags_with_weight_for(:"#{tags_name}")
77
- end
78
-
79
- def #{tags_name}_separator
80
- get_tag_separator_for(:"#{tags_name}")
81
- end
82
-
83
- def #{tags_name}_separator=(value)
84
- set_tag_separator_for(:"#{tags_name}", value)
85
- end
86
-
87
- def #{tags_name}_tagged_with(tags)
88
- tagged_with(:"#{tags_name}", tags)
89
- end
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)
90
81
  end
91
- END
82
+ end
92
83
 
93
- # instance methods
94
- class_eval <<-END
95
- def #{options[:string_method]}
96
- convert_array_to_string(#{database_field}, get_tag_separator_for(:"#{tags_name}"))
84
+ #instance methods
85
+ class_eval do
86
+ define_method :"#{options[:field]}_string" do
87
+ tags_string_for(options[:field])
97
88
  end
98
- def #{tags_name}=(value)
99
- write_attribute(:#{database_field}, format_tags_for_write(value, get_tag_separator_for(:"#{tags_name}")))
89
+
90
+ define_method :"#{options[:field]}=" do |value|
91
+ write_attribute(options[:field], self.class.format_tags_for(options[:field], value))
100
92
  end
101
- END
93
+ end
102
94
  end
103
95
 
104
96
  def tag_contexts
105
97
  self.taggable_with_context_options.keys
106
98
  end
107
-
99
+
108
100
  def tag_database_fields
109
101
  self.taggable_with_context_options.keys.map do |context|
110
- tag_options_for(context)[:field]
102
+ tag_options_for(context)[:db_field]
111
103
  end
112
104
  end
113
105
 
@@ -127,9 +119,6 @@ module Mongoid::TaggableWithContext
127
119
  self.taggable_with_context_options[context][:separator]
128
120
  end
129
121
 
130
- def set_tag_separator_for(context, value)
131
- self.taggable_with_context_options[context][:separator] = value.nil? ? TAGGABLE_DEFAULT_SEPARATOR : value.to_s
132
- end
133
122
 
134
123
  # Find documents tagged with all tags passed as a parameter, given
135
124
  # as an Array or a String using the configured separator.
@@ -143,39 +132,32 @@ module Mongoid::TaggableWithContext
143
132
  # @param [ Array<String, Symbol>, String ] :tags Tags to match.
144
133
  # @return [ Criteria ] A new criteria.
145
134
  def tagged_with(context, tags)
146
- tags = convert_string_to_array(tags, get_tag_separator_for(context)) if tags.is_a? String
147
- database_field = tag_options_for(context)[:field]
148
- all_in(database_field => tags)
135
+ tags = format_tags_for(context, tags)
136
+ field = tag_options_for(context)[:field]
137
+ all_in(field => tags)
149
138
  end
150
139
 
151
140
  # Helper method to convert a a tag input value of unknown type
152
141
  # to a formatted array.
153
- def format_tags_for_write(value, separator = TAGGABLE_DEFAULT_SEPARATOR)
154
- if value.is_a? Array
155
- clean_up_array(value)
156
- else
157
- convert_string_to_array(value, separator)
158
- end
142
+ def format_tags_for(context, value)
143
+ # 0) Tags must be an array or a string
144
+ raise InvalidTagsFormat unless value.is_a?(Array) || value.is_a?(String)
145
+ # 1) convert String to Array
146
+ value = value.split(get_tag_separator_for(context)) if value.is_a? String
147
+ # 2) remove all nil values
148
+ # 3) strip all white spaces. Could leave blank strings (e.g. foo, , bar, baz)
149
+ # 4) remove all blank strings
150
+ # 5) remove duplicate
151
+ value.compact.map(&:strip).reject(&:blank?).uniq
159
152
  end
160
153
 
161
- # Helper method to convert a String to an Array based on the
162
- # configured tag separator.
163
- def convert_string_to_array(str = "", separator = TAGGABLE_DEFAULT_SEPARATOR)
164
- clean_up_array(str.split(separator))
165
- end
154
+ protected
166
155
 
167
- def convert_array_to_string(ary = [], separator = TAGGABLE_DEFAULT_SEPARATOR)
168
- #ary.join(separator)
169
- (ary || []).join(separator)
156
+ # Prepares valid Mongoid option keys from the taggable options
157
+ # @param [ Hash ] :options The taggable options hash.
158
+ # @return [ Hash ] A options hash for the Mongoid #field method.
159
+ def mongoid_field_options(options = {})
160
+ options.slice(*::Mongoid::Fields::Validators::Macro::OPTIONS).merge!(type: Array)
170
161
  end
171
-
172
- def clean_up_array(ary = [])
173
- # 0). remove all nil values
174
- # 1). strip all white spaces. Could leave blank strings (e.g. foo, , bar, baz)
175
- # 2). remove all blank strings
176
- # 3). remove duplicate
177
- ary.compact.map(&:strip).reject(&:blank?).uniq
178
- end
179
-
180
162
  end
181
163
  end
@@ -2,9 +2,9 @@ module Mongoid::TaggableWithContext::AggregationStrategy
2
2
  module MapReduce
3
3
  extend ActiveSupport::Concern
4
4
  included do
5
- set_callback :save, :after, :map_reduce_all_contexts!, :if => :tags_changed?
5
+ set_callback :save, :after, :map_reduce_all_contexts!, if: :tags_changed?
6
6
  set_callback :destroy, :after, :map_reduce_all_contexts!
7
- delegate :aggregation_collection_for, :to => "self.class"
7
+ delegate :aggregation_collection_for, to: "self.class"
8
8
  end
9
9
 
10
10
  module ClassMethods
@@ -19,13 +19,13 @@ module Mongoid::TaggableWithContext::AggregationStrategy
19
19
  end
20
20
 
21
21
  def tags_for(context, conditions={})
22
- aggregation_database_collection_for(context).find({:value => {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| t["_id"] }
22
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| t["_id"] }
23
23
  end
24
24
 
25
25
  # retrieve the list of tag with weight(count), this is useful for
26
26
  # creating tag clouds
27
27
  def tags_with_weight_for(context, conditions={})
28
- aggregation_database_collection_for(context).find({:value => {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| [t["_id"], t["value"].to_i] }
28
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(_id: 1).to_a.map{ |t| [t["_id"], t["value"].to_i] }
29
29
  end
30
30
 
31
31
  end
@@ -33,7 +33,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
33
33
  protected
34
34
 
35
35
  def changed_tag_arrays
36
- tag_database_fields & changes.keys.map(&:to_sym)
36
+ self.class.tag_database_fields & changes.keys.map(&:to_sym)
37
37
  end
38
38
 
39
39
  def tags_changed?
@@ -41,19 +41,19 @@ module Mongoid::TaggableWithContext::AggregationStrategy
41
41
  end
42
42
 
43
43
  def map_reduce_all_contexts!
44
- tag_contexts.each do |context|
44
+ self.class.tag_contexts.each do |context|
45
45
  map_reduce_context!(context)
46
46
  end
47
47
  end
48
48
 
49
49
  def map_reduce_context!(context)
50
- field = tag_options_for(context)[:field]
50
+ db_field = self.class.tag_options_for(context)[:db_field]
51
51
 
52
52
  map = <<-END
53
53
  function() {
54
- if (!this.#{field})return;
55
- for (index in this.#{field})
56
- emit(this.#{field}[index], 1);
54
+ if (!this.#{db_field})return;
55
+ for (index in this.#{db_field})
56
+ emit(this.#{db_field}[index], 1);
57
57
  }
58
58
  END
59
59
 
@@ -23,13 +23,13 @@ module Mongoid::TaggableWithContext::AggregationStrategy
23
23
  end
24
24
 
25
25
  def tags_for(context, conditions={})
26
- aggregation_database_collection_for(context).find({:value => {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| t[tag_name_attribute] }
26
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| t[tag_name_attribute] }
27
27
  end
28
28
 
29
29
  # retrieve the list of tag with weight(count), this is useful for
30
30
  # creating tag clouds
31
31
  def tags_with_weight_for(context, conditions={})
32
- aggregation_database_collection_for(context).find({:value => {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
32
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }}).sort(tag_name_attribute.to_sym => 1).to_a.map{ |t| [t[tag_name_attribute], t["value"].to_i] }
33
33
  end
34
34
 
35
35
  def recalculate_all_context_tag_weights!
@@ -75,8 +75,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
75
75
  {self.class.tag_name_attribute.to_sym => tag}
76
76
  end
77
77
 
78
- def update_tags_aggregation(database_field, old_tags=[], new_tags=[])
79
- context = database_field_to_context_hash[database_field]
78
+ def update_tags_aggregation(context, old_tags=[], new_tags=[])
80
79
  coll = self.class.aggregation_database_collection_for(context)
81
80
 
82
81
  old_tags ||= []
@@ -87,10 +86,10 @@ module Mongoid::TaggableWithContext::AggregationStrategy
87
86
 
88
87
 
89
88
  tags_removed.each do |tag|
90
- coll.find(get_conditions(context, tag)).upsert({'$inc' => {:value => -1}})
89
+ coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: -1}})
91
90
  end
92
91
  tags_added.each do |tag|
93
- coll.find(get_conditions(context, tag)).upsert({'$inc' => {:value => 1}})
92
+ coll.find(get_conditions(context, tag)).upsert({'$inc' => {value: 1}})
94
93
  end
95
94
  #coll.find({_id: {"$in" => tags_removed}}).update({'$inc' => {:value => -1}}, [:upsert])
96
95
  #coll.find({_id: {"$in" => tags_added}}).update({'$inc' => {:value => 1}}, [:upsert])
@@ -98,7 +97,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
98
97
 
99
98
  def update_tags_aggregations_on_save
100
99
  indifferent_changes = HashWithIndifferentAccess.new changes
101
- tag_database_fields.each do |field|
100
+ self.class.tag_database_fields.each do |field|
102
101
  next if indifferent_changes[field].nil?
103
102
 
104
103
  old_tags, new_tags = indifferent_changes[field]
@@ -107,7 +106,7 @@ module Mongoid::TaggableWithContext::AggregationStrategy
107
106
  end
108
107
 
109
108
  def update_tags_aggregations_on_destroy
110
- tag_database_fields.each do |field|
109
+ self.class.tag_database_fields.each do |field|
111
110
  old_tags = send field
112
111
  new_tags = []
113
112
  update_tags_aggregation(field, old_tags, new_tags)
@@ -35,7 +35,7 @@ module Mongoid::TaggableWithContext::GroupBy::AggregationStrategy
35
35
 
36
36
  protected
37
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)
38
+ aggregation_database_collection_for(context).find({value: {"$gt" => 0 }, group_by_field: group_by}).sort(tag_name_attribute.to_sym => 1)
39
39
  end
40
40
  end
41
41
 
@@ -45,7 +45,7 @@ module Mongoid::TaggableWithContext::GroupBy::AggregationStrategy
45
45
  conditions = {self.class.tag_name_attribute.to_sym => tag}
46
46
  group_by_field = self.class.get_tag_group_by_field_for(context)
47
47
  if group_by_field
48
- conditions.merge!({:group_by_field => self.send(group_by_field)})
48
+ conditions.merge!({group_by_field: self.send(group_by_field)})
49
49
  end
50
50
  conditions
51
51
  end
@@ -7,24 +7,23 @@ module Mongoid::TaggableWithContext::GroupBy
7
7
  def taggable(*args)
8
8
  super(*args)
9
9
  args.extract_options!
10
- tags_field = (args.blank? ? :tags : args.shift).to_sym
11
- self.taggable_with_context_options[tags_field].reverse_merge!(:group_by_field => nil)
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
12
 
13
- class_eval <<-END
14
- class << self
15
- def #{tags_field}(group_by=nil)
16
- tags_for(:"#{tags_field}", group_by)
17
- end
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
18
 
19
- def #{tags_field}_with_weight(group_by=nil)
20
- tags_with_weight_for(:"#{tags_field}", group_by)
21
- end
19
+ define_method :"#{tags_field}_with_weight" do |group_by = nil|
20
+ tags_with_weight_for(tags_field, group_by)
21
+ end
22
22
 
23
- def #{tags_field}_group_by_field
24
- get_tag_group_by_field_for(:"#{tags_field}")
25
- end
23
+ define_method :"#{tags_field}_group_by_field" do
24
+ get_tag_group_by_field_for(tags_field)
26
25
  end
27
- END
26
+ end
28
27
  end
29
28
 
30
29
  def tags_for(context, group_by, conditions={})
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module TaggableWithContext
4
+ VERSION = '1.1.0'
5
+ end
6
+ end
@@ -4,4 +4,5 @@ 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
6
  require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/group_by/taggable_with_context')
7
- require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/group_by/aggregation_strategy/real_time')
7
+ require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/group_by/aggregation_strategy/real_time')
8
+ require File.join(File.dirname(__FILE__), 'mongoid/taggable_with_context/version')
@@ -1,17 +1,16 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "mongoid_taggable_with_context"
8
- s.version = "1.0.1"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Aaron Qian"] #["Johnny Shields", "Steve Chung", "Luca G. Soave", "Aaron Qian"]
12
- s.date = "2013-02-18"
13
- s.description = "It provides some helpers to create taggable documents with context."
14
- s.email = ["aq1018@gmail.com"]
11
+ s.authors = ["Aaron Qian", "Luca G. Soave", "John Shields", "Wilker Lucio", "Ches Martin"]
12
+ s.date = "2013-05-18"
13
+ s.description = "Add multiple tag fields on Mongoid documents with aggregation capability."
15
14
  s.extra_rdoc_files = [
16
15
  "LICENSE.txt",
17
16
  "README.md"
@@ -23,13 +22,13 @@ Gem::Specification.new do |s|
23
22
  "LICENSE.txt",
24
23
  "README.md",
25
24
  "Rakefile",
26
- "VERSION",
27
25
  "init.rb",
28
26
  "lib/mongoid/taggable_with_context.rb",
29
27
  "lib/mongoid/taggable_with_context/aggregation_strategy/map_reduce.rb",
30
28
  "lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb",
31
29
  "lib/mongoid/taggable_with_context/group_by/aggregation_strategy/real_time.rb",
32
30
  "lib/mongoid/taggable_with_context/group_by/taggable_with_context.rb",
31
+ "lib/mongoid/taggable_with_context/version.rb",
33
32
  "lib/mongoid_taggable_with_context.rb",
34
33
  "mongoid_taggable_with_context.gemspec",
35
34
  "spec/mongoid_taggable_with_context_spec.rb",
@@ -40,10 +39,6 @@ Gem::Specification.new do |s|
40
39
  s.require_paths = ["lib"]
41
40
  s.rubygems_version = "1.8.24"
42
41
  s.summary = "Mongoid taggable behaviour"
43
- s.test_files = [
44
- "spec/mongoid_taggable_with_context_spec.rb",
45
- "spec/spec_helper.rb"
46
- ]
47
42
 
48
43
  if s.respond_to? :specification_version then
49
44
  s.specification_version = 3
@@ -6,7 +6,7 @@ class MyModel
6
6
 
7
7
  taggable
8
8
  taggable :artists
9
- taggable :albums, :default => []
9
+ taggable :albums, default: []
10
10
  end
11
11
 
12
12
  class M1
@@ -15,7 +15,7 @@ class M1
15
15
  include Mongoid::TaggableWithContext::AggregationStrategy::MapReduce
16
16
 
17
17
  taggable
18
- taggable :artists
18
+ taggable :a, as: :artists
19
19
  end
20
20
 
21
21
  class M2
@@ -32,8 +32,8 @@ class M3
32
32
  include Mongoid::TaggableWithContext::GroupBy::AggregationStrategy::RealTime
33
33
 
34
34
  field :user
35
- taggable :group_by_field => :user
36
- taggable :artists, :group_by_field => :user
35
+ taggable group_by_field: :user
36
+ taggable :artists, group_by_field: :user
37
37
  end
38
38
 
39
39
  describe Mongoid::TaggableWithContext do
@@ -119,35 +119,11 @@ describe Mongoid::TaggableWithContext do
119
119
  end
120
120
  end
121
121
 
122
- context "changing separator" do
123
- before :all do
124
- MyModel.tags_separator = ";"
125
- end
126
-
127
- after :all do
128
- MyModel.tags_separator = " "
129
- end
130
-
131
- before :each do
132
- @m = MyModel.new
133
- end
134
-
135
- it "should split with custom separator" do
136
- @m.tags = "some;other;separator"
137
- @m.tags.should == %w[some other separator]
138
- end
139
-
140
- it "should join string with custom separator" do
141
- @m.tags = %w[some other sep]
142
- @m.tags_string.should == "some;other;sep"
143
- end
144
- end
145
-
146
122
  context "tagged_with" do
147
123
  before :each do
148
- @m1 = MyModel.create!(:tags => "food ant bee", :artists => "jeff greg mandy aaron andy")
149
- @m2 = MyModel.create!(:tags => "juice food bee zip", :artists => "grant andrew andy")
150
- @m3 = MyModel.create!(:tags => "honey strip food", :artists => "mandy aaron andy")
124
+ @m1 = MyModel.create!(tags: "food ant bee", artists: "jeff greg mandy aaron andy")
125
+ @m2 = MyModel.create!(tags: "juice food bee zip", artists: "grant andrew andy")
126
+ @m3 = MyModel.create!(tags: "honey strip food", artists: "mandy aaron andy")
151
127
  end
152
128
 
153
129
  it "should retrieve a list of documents" do
@@ -181,9 +157,9 @@ describe Mongoid::TaggableWithContext do
181
157
 
182
158
  context "on create directly" do
183
159
  before :each do
184
- klass.create!(:user => "user1", :tags => "food ant bee", :artists => "jeff greg mandy aaron andy")
185
- klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
186
- klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
160
+ klass.create!(user: "user1", tags: "food ant bee", artists: "jeff greg mandy aaron andy")
161
+ klass.create!(user: "user1", tags: "juice food bee zip", artists: "grant andrew andy")
162
+ klass.create!(user: "user2", tags: "honey strip food", artists: "mandy aaron andy")
187
163
  end
188
164
 
189
165
  it "should retrieve the list of all saved tags distinct and ordered" do
@@ -262,9 +238,9 @@ describe Mongoid::TaggableWithContext do
262
238
 
263
239
  context "on create then update" do
264
240
  before :each do
265
- m1 = klass.create!(:user => "user1", :tags => "food ant bee", :artists => "jeff greg mandy aaron andy")
266
- m2 = klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
267
- m3 = klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
241
+ m1 = klass.create!(user: "user1", tags: "food ant bee", artists: "jeff greg mandy aaron andy")
242
+ m2 = klass.create!(user: "user1", tags: "juice food bee zip", artists: "grant andrew andy")
243
+ m3 = klass.create!(user: "user2", tags: "honey strip food", artists: "mandy aaron andy")
268
244
 
269
245
  m1.tags = m1.tags + %w[honey strip shoe]
270
246
  m1.save!
@@ -305,9 +281,9 @@ describe Mongoid::TaggableWithContext do
305
281
 
306
282
  context "on create, update, then destroy" do
307
283
  before :each do
308
- m1 = klass.create!(:user => "user1", :tags => "food ant bee", :artists => "jeff greg mandy aaron andy")
309
- m2 = klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
310
- m3 = klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
284
+ m1 = klass.create!(user: "user1", tags: "food ant bee", artists: "jeff greg mandy aaron andy")
285
+ m2 = klass.create!(user: "user1", tags: "juice food bee zip", artists: "grant andrew andy")
286
+ m3 = klass.create!(user: "user2", tags: "honey strip food", artists: "mandy aaron andy")
311
287
 
312
288
  m1.tags = m1.tags + %w[honey strip shoe] - %w[food]
313
289
  m1.save!
@@ -377,6 +353,10 @@ describe Mongoid::TaggableWithContext do
377
353
  let(:klass) { M3 }
378
354
  it_should_behave_like "aggregation"
379
355
 
356
+ it "should have artists_group_by_field value :user" do
357
+ klass.artists_group_by_field.should == :user
358
+ end
359
+
380
360
  it "should generate the tags aggregation collection name correctly" do
381
361
  klass.aggregation_collection_for(:tags).should == "m3s_tags_aggregation"
382
362
  end
@@ -387,9 +367,9 @@ describe Mongoid::TaggableWithContext do
387
367
 
388
368
  context "for groupings" do
389
369
  before :each do
390
- klass.create!(:user => "user1", :tags => "food ant bee", :artists => "jeff greg mandy aaron andy")
391
- klass.create!(:user => "user1", :tags => "juice food bee zip", :artists => "grant andrew andy")
392
- klass.create!(:user => "user2", :tags => "honey strip food", :artists => "mandy aaron andy")
370
+ klass.create!(user: "user1", tags: "food ant bee", artists: "jeff greg mandy aaron andy")
371
+ klass.create!(user: "user1", tags: "juice food bee zip", artists: "grant andrew andy")
372
+ klass.create!(user: "user2", tags: "honey strip food", artists: "mandy aaron andy")
393
373
  end
394
374
 
395
375
  it "should retrieve the list of all saved tags distinct and ordered" do
@@ -433,4 +413,25 @@ describe Mongoid::TaggableWithContext do
433
413
  end
434
414
  end
435
415
  end
416
+
417
+ context "removed options" do
418
+ it "should throw error if :field option is specified" do
419
+ expect do
420
+ class Invalid
421
+ include Mongoid::Document
422
+ include Mongoid::TaggableWithContext
423
+ taggable field: :foobar
424
+ end
425
+ end.to raise_error
426
+ end
427
+ it "should throw error if :string_method option is specified" do
428
+ expect do
429
+ class Invalid
430
+ include Mongoid::Document
431
+ include Mongoid::TaggableWithContext
432
+ taggable string_method: :foobar
433
+ end
434
+ end.to raise_error
435
+ end
436
+ end
436
437
  end
metadata CHANGED
@@ -1,115 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_taggable_with_context
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Aaron Qian
8
+ - Luca G. Soave
9
+ - John Shields
10
+ - Wilker Lucio
11
+ - Ches Martin
9
12
  autorequire:
10
13
  bindir: bin
11
14
  cert_chain: []
12
- date: 2013-02-18 00:00:00.000000000 Z
15
+ date: 2013-05-18 00:00:00.000000000 Z
13
16
  dependencies:
14
17
  - !ruby/object:Gem::Dependency
15
18
  name: mongoid
16
19
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
20
  requirements:
19
- - - ! '>='
21
+ - - '>='
20
22
  - !ruby/object:Gem::Version
21
23
  version: 3.0.0
22
24
  type: :runtime
23
25
  prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
27
  requirements:
27
- - - ! '>='
28
+ - - '>='
28
29
  - !ruby/object:Gem::Version
29
30
  version: 3.0.0
30
31
  - !ruby/object:Gem::Dependency
31
32
  name: database_cleaner
32
33
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
34
  requirements:
35
- - - ! '>='
35
+ - - '>='
36
36
  - !ruby/object:Gem::Version
37
37
  version: '0'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
41
  requirements:
43
- - - ! '>='
42
+ - - '>='
44
43
  - !ruby/object:Gem::Version
45
44
  version: '0'
46
45
  - !ruby/object:Gem::Dependency
47
46
  name: rspec
48
47
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
48
  requirements:
51
- - - ! '>='
49
+ - - '>='
52
50
  - !ruby/object:Gem::Version
53
51
  version: '0'
54
52
  type: :development
55
53
  prerelease: false
56
54
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
55
  requirements:
59
- - - ! '>='
56
+ - - '>='
60
57
  - !ruby/object:Gem::Version
61
58
  version: '0'
62
59
  - !ruby/object:Gem::Dependency
63
60
  name: yard
64
61
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
62
  requirements:
67
- - - ! '>='
63
+ - - '>='
68
64
  - !ruby/object:Gem::Version
69
65
  version: '0'
70
66
  type: :development
71
67
  prerelease: false
72
68
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
69
  requirements:
75
- - - ! '>='
70
+ - - '>='
76
71
  - !ruby/object:Gem::Version
77
72
  version: '0'
78
73
  - !ruby/object:Gem::Dependency
79
74
  name: bundler
80
75
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
76
  requirements:
83
- - - ! '>='
77
+ - - '>='
84
78
  - !ruby/object:Gem::Version
85
79
  version: 1.0.0
86
80
  type: :development
87
81
  prerelease: false
88
82
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
83
  requirements:
91
- - - ! '>='
84
+ - - '>='
92
85
  - !ruby/object:Gem::Version
93
86
  version: 1.0.0
94
87
  - !ruby/object:Gem::Dependency
95
88
  name: jeweler
96
89
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
90
  requirements:
99
- - - ! '>='
91
+ - - '>='
100
92
  - !ruby/object:Gem::Version
101
93
  version: '0'
102
94
  type: :development
103
95
  prerelease: false
104
96
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
97
  requirements:
107
- - - ! '>='
98
+ - - '>='
108
99
  - !ruby/object:Gem::Version
109
100
  version: '0'
110
- description: It provides some helpers to create taggable documents with context.
111
- email:
112
- - aq1018@gmail.com
101
+ description: Add multiple tag fields on Mongoid documents with aggregation capability.
102
+ email:
113
103
  executables: []
114
104
  extensions: []
115
105
  extra_rdoc_files:
@@ -122,13 +112,13 @@ files:
122
112
  - LICENSE.txt
123
113
  - README.md
124
114
  - Rakefile
125
- - VERSION
126
115
  - init.rb
127
116
  - lib/mongoid/taggable_with_context.rb
128
117
  - lib/mongoid/taggable_with_context/aggregation_strategy/map_reduce.rb
129
118
  - lib/mongoid/taggable_with_context/aggregation_strategy/real_time.rb
130
119
  - lib/mongoid/taggable_with_context/group_by/aggregation_strategy/real_time.rb
131
120
  - lib/mongoid/taggable_with_context/group_by/taggable_with_context.rb
121
+ - lib/mongoid/taggable_with_context/version.rb
132
122
  - lib/mongoid_taggable_with_context.rb
133
123
  - mongoid_taggable_with_context.gemspec
134
124
  - spec/mongoid_taggable_with_context_spec.rb
@@ -136,29 +126,26 @@ files:
136
126
  homepage: http://github.com/lgs/mongoid_taggable_with_context
137
127
  licenses:
138
128
  - MIT
129
+ metadata: {}
139
130
  post_install_message:
140
131
  rdoc_options: []
141
132
  require_paths:
142
133
  - lib
143
134
  required_ruby_version: !ruby/object:Gem::Requirement
144
- none: false
145
135
  requirements:
146
- - - ! '>='
136
+ - - '>='
147
137
  - !ruby/object:Gem::Version
148
138
  version: '0'
149
139
  required_rubygems_version: !ruby/object:Gem::Requirement
150
- none: false
151
140
  requirements:
152
- - - ! '>='
141
+ - - '>='
153
142
  - !ruby/object:Gem::Version
154
143
  version: '0'
155
144
  requirements: []
156
145
  rubyforge_project:
157
- rubygems_version: 1.8.25
146
+ rubygems_version: 2.0.3
158
147
  signing_key:
159
148
  specification_version: 3
160
149
  summary: Mongoid taggable behaviour
161
- test_files:
162
- - spec/mongoid_taggable_with_context_spec.rb
163
- - spec/spec_helper.rb
150
+ test_files: []
164
151
  has_rdoc:
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.0