mongoid 2.3.5 → 2.4.0

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.
Files changed (126) hide show
  1. data/CHANGELOG.md +34 -176
  2. data/LICENSE +1 -1
  3. data/lib/config/locales/bg.yml +6 -0
  4. data/lib/config/locales/de.yml +6 -0
  5. data/lib/config/locales/en-GB.yml +8 -0
  6. data/lib/config/locales/en.yml +8 -0
  7. data/lib/config/locales/es.yml +9 -3
  8. data/lib/config/locales/fr.yml +6 -0
  9. data/lib/config/locales/hi.yml +6 -0
  10. data/lib/config/locales/hu.yml +6 -0
  11. data/lib/config/locales/id.yml +6 -0
  12. data/lib/config/locales/it.yml +6 -0
  13. data/lib/config/locales/ja.yml +6 -0
  14. data/lib/config/locales/kr.yml +6 -0
  15. data/lib/config/locales/nl.yml +8 -0
  16. data/lib/config/locales/pl.yml +6 -0
  17. data/lib/config/locales/pt-BR.yml +6 -0
  18. data/lib/config/locales/pt.yml +8 -2
  19. data/lib/config/locales/ro.yml +6 -0
  20. data/lib/config/locales/ru.yml +6 -0
  21. data/lib/config/locales/sv.yml +6 -0
  22. data/lib/config/locales/vi.yml +14 -8
  23. data/lib/config/locales/zh-CN.yml +6 -0
  24. data/lib/mongoid/atomic.rb +62 -13
  25. data/lib/mongoid/atomic/modifiers.rb +33 -1
  26. data/lib/mongoid/attributes.rb +5 -19
  27. data/lib/mongoid/callbacks.rb +2 -1
  28. data/lib/mongoid/collection.rb +2 -2
  29. data/lib/mongoid/collections/retry.rb +18 -6
  30. data/lib/mongoid/components.rb +2 -0
  31. data/lib/mongoid/config.rb +8 -63
  32. data/lib/mongoid/config/environment.rb +41 -0
  33. data/lib/mongoid/config/options.rb +74 -0
  34. data/lib/mongoid/contexts/enumerable.rb +0 -24
  35. data/lib/mongoid/contexts/mongo.rb +33 -3
  36. data/lib/mongoid/copyable.rb +1 -1
  37. data/lib/mongoid/criteria.rb +4 -2
  38. data/lib/mongoid/criterion/inclusion.rb +1 -16
  39. data/lib/mongoid/criterion/optional.rb +37 -10
  40. data/lib/mongoid/criterion/scoping.rb +83 -0
  41. data/lib/mongoid/criterion/selector.rb +9 -6
  42. data/lib/mongoid/default_scope.rb +1 -1
  43. data/lib/mongoid/dirty.rb +163 -29
  44. data/lib/mongoid/document.rb +58 -7
  45. data/lib/mongoid/errors.rb +2 -0
  46. data/lib/mongoid/errors/no_environment.rb +19 -0
  47. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  48. data/lib/mongoid/extensions.rb +6 -0
  49. data/lib/mongoid/extensions/array/deep_copy.rb +25 -0
  50. data/lib/mongoid/extensions/hash/deep_copy.rb +25 -0
  51. data/lib/mongoid/extensions/hash/scoping.rb +1 -1
  52. data/lib/mongoid/extensions/object/deep_copy.rb +21 -0
  53. data/lib/mongoid/extensions/proc/scoping.rb +2 -2
  54. data/lib/mongoid/extensions/symbol/inflections.rb +1 -0
  55. data/lib/mongoid/fields.rb +171 -104
  56. data/lib/mongoid/fields/{serializable → internal}/array.rb +33 -1
  57. data/lib/mongoid/fields/{serializable → internal}/big_decimal.rb +16 -1
  58. data/lib/mongoid/fields/{serializable → internal}/bignum.rb +1 -1
  59. data/lib/mongoid/fields/{serializable → internal}/binary.rb +1 -1
  60. data/lib/mongoid/fields/{serializable → internal}/boolean.rb +16 -1
  61. data/lib/mongoid/fields/{serializable → internal}/date.rb +1 -1
  62. data/lib/mongoid/fields/{serializable → internal}/date_time.rb +1 -1
  63. data/lib/mongoid/fields/{serializable → internal}/fixnum.rb +1 -1
  64. data/lib/mongoid/fields/{serializable → internal}/float.rb +16 -1
  65. data/lib/mongoid/fields/internal/foreign_keys/array.rb +74 -0
  66. data/lib/mongoid/fields/{serializable → internal}/foreign_keys/object.rb +11 -2
  67. data/lib/mongoid/fields/{serializable → internal}/hash.rb +1 -1
  68. data/lib/mongoid/fields/{serializable → internal}/integer.rb +16 -1
  69. data/lib/mongoid/fields/{serializable → internal}/localized.rb +23 -2
  70. data/lib/mongoid/fields/{serializable → internal}/nil_class.rb +16 -1
  71. data/lib/mongoid/fields/{serializable → internal}/object.rb +1 -1
  72. data/lib/mongoid/fields/{serializable → internal}/object_id.rb +16 -1
  73. data/lib/mongoid/fields/{serializable → internal}/range.rb +21 -2
  74. data/lib/mongoid/fields/{serializable → internal}/set.rb +16 -1
  75. data/lib/mongoid/fields/{serializable → internal}/string.rb +16 -1
  76. data/lib/mongoid/fields/{serializable → internal}/symbol.rb +17 -1
  77. data/lib/mongoid/fields/{serializable → internal}/time.rb +1 -1
  78. data/lib/mongoid/fields/{serializable → internal}/time_with_zone.rb +1 -1
  79. data/lib/mongoid/fields/{serializable → internal}/timekeeping.rb +16 -1
  80. data/lib/mongoid/fields/mappings.rb +8 -3
  81. data/lib/mongoid/fields/serializable.rb +34 -3
  82. data/lib/mongoid/hierarchy.rb +14 -14
  83. data/lib/mongoid/identity_map.rb +3 -2
  84. data/lib/mongoid/logger.rb +1 -7
  85. data/lib/mongoid/named_scope.rb +16 -12
  86. data/lib/mongoid/observer.rb +5 -1
  87. data/lib/mongoid/paranoia.rb +1 -0
  88. data/lib/mongoid/persistence.rb +11 -4
  89. data/lib/mongoid/persistence/atomic.rb +4 -1
  90. data/lib/mongoid/persistence/atomic/add_to_set.rb +17 -1
  91. data/lib/mongoid/persistence/atomic/sets.rb +1 -1
  92. data/lib/mongoid/railties/database.rake +1 -1
  93. data/lib/mongoid/relations.rb +1 -3
  94. data/lib/mongoid/relations/auto_save.rb +1 -1
  95. data/lib/mongoid/relations/builders.rb +1 -1
  96. data/lib/mongoid/relations/builders/embedded/many.rb +2 -6
  97. data/lib/mongoid/relations/builders/nested_attributes/many.rb +1 -1
  98. data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
  99. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -1
  100. data/lib/mongoid/relations/cascading/delete.rb +1 -1
  101. data/lib/mongoid/relations/cyclic.rb +10 -6
  102. data/lib/mongoid/relations/embedded/atomic.rb +3 -3
  103. data/lib/mongoid/relations/embedded/many.rb +98 -20
  104. data/lib/mongoid/relations/macros.rb +2 -0
  105. data/lib/mongoid/relations/many.rb +13 -0
  106. data/lib/mongoid/relations/metadata.rb +3 -3
  107. data/lib/mongoid/relations/nested_builder.rb +4 -3
  108. data/lib/mongoid/relations/proxy.rb +0 -1
  109. data/lib/mongoid/relations/referenced/batch.rb +3 -2
  110. data/lib/mongoid/relations/referenced/in.rb +3 -3
  111. data/lib/mongoid/relations/referenced/many.rb +89 -10
  112. data/lib/mongoid/relations/referenced/many_to_many.rb +34 -43
  113. data/lib/mongoid/relations/referenced/one.rb +8 -4
  114. data/lib/mongoid/relations/synchronization.rb +22 -5
  115. data/lib/mongoid/threaded.rb +38 -276
  116. data/lib/mongoid/threaded/lifecycle.rb +18 -18
  117. data/lib/mongoid/timestamps/updated.rb +13 -3
  118. data/lib/mongoid/validations.rb +22 -1
  119. data/lib/mongoid/validations/presence.rb +40 -0
  120. data/lib/mongoid/validations/uniqueness.rb +14 -3
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/versioning.rb +6 -2
  123. data/lib/rails/mongoid.rb +7 -1
  124. metadata +64 -45
  125. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +0 -42
  126. data/lib/mongoid/relations/embedded/sort.rb +0 -31
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Config
4
+
5
+ # Encapsulates logic for getting environment information.
6
+ module Environment
7
+ extend self
8
+
9
+ # Get the name of the environment that we are running under. This first
10
+ # looks for Rails, then Sinatra, then a RACK_ENV environment variable,
11
+ # and if none of those are found returns "development".
12
+ #
13
+ # @example Get the env name.
14
+ # Environment.env_name
15
+ #
16
+ # @return [ String ] The name of the current environment.
17
+ #
18
+ # @since 2.3.0
19
+ def env_name
20
+ return Rails.env if defined?(Rails)
21
+ return Sinatra::Base.environment.to_s if defined?(Sinatra)
22
+ ENV["RACK_ENV"] || raise(Errors::NoEnvironment.new)
23
+ end
24
+
25
+ # Load the yaml from the provided path and return the settings for the
26
+ # current environment.
27
+ #
28
+ # @example Load the yaml.
29
+ # Environment.load_yaml("/work/mongoid.yml")
30
+ #
31
+ # @param [ String ] path The location of the file.
32
+ #
33
+ # @return [ Hash ] The settings.
34
+ #
35
+ # @since 2.3.0
36
+ def load_yaml(path)
37
+ YAML.load(ERB.new(File.new(path).read).result)[env_name]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc
3
+ module Config
4
+
5
+ # Encapsulates logic for setting options.
6
+ module Options
7
+
8
+ # Get the defaults or initialize a new empty hash.
9
+ #
10
+ # @example Get the defaults.
11
+ # options.defaults
12
+ #
13
+ # @return [ Hash ] The default options.
14
+ #
15
+ # @since 2.3.0
16
+ def defaults
17
+ @defaults ||= {}
18
+ end
19
+
20
+ # Define a configuration option with a default.
21
+ #
22
+ # @example Define the option.
23
+ # Options.option(:persist_in_safe_mode, :default => false)
24
+ #
25
+ # @param [ Symbol ] name The name of the configuration option.
26
+ # @param [ Hash ] options Extras for the option.
27
+ #
28
+ # @option options [ Object ] :default The default value.
29
+ #
30
+ # @since 2.0.0.rc.1
31
+ def option(name, options = {})
32
+ defaults[name] = settings[name] = options[:default]
33
+
34
+ class_eval <<-RUBY
35
+ def #{name}
36
+ settings[#{name.inspect}]
37
+ end
38
+
39
+ def #{name}=(value)
40
+ settings[#{name.inspect}] = value
41
+ end
42
+
43
+ def #{name}?
44
+ #{name}
45
+ end
46
+ RUBY
47
+ end
48
+
49
+ # Reset the configuration options to the defaults.
50
+ #
51
+ # @example Reset the configuration options.
52
+ # config.reset
53
+ #
54
+ # @return [ Hash ] The defaults.
55
+ #
56
+ # @since 2.3.0
57
+ def reset
58
+ settings.replace(defaults)
59
+ end
60
+
61
+ # Get the settings or initialize a new empty hash.
62
+ #
63
+ # @example Get the settings.
64
+ # options.settings
65
+ #
66
+ # @return [ Hash ] The setting options.
67
+ #
68
+ # @since 2.3.0
69
+ def settings
70
+ @settings ||= {}
71
+ end
72
+ end
73
+ end
74
+ end
@@ -210,18 +210,6 @@ module Mongoid #:nodoc:
210
210
 
211
211
  protected
212
212
 
213
- # Get the root class collection name.
214
- #
215
- # @example Get the root class collection name.
216
- # context.collection_name
217
- #
218
- # @return [ String ] The name of the collection.
219
- #
220
- # @since 2.4.3
221
- def collection_name
222
- root ? root.collection_name : nil
223
- end
224
-
225
213
  # Filters the documents against the criteria's selector
226
214
  #
227
215
  # @example Filter the documents.
@@ -263,22 +251,10 @@ module Mongoid #:nodoc:
263
251
  documents
264
252
  end
265
253
 
266
- # Get the root document for the enumerable.
267
- #
268
- # @example Get the root document.
269
- # context.root
270
- #
271
- # @return [ Document ] The root.
272
254
  def root
273
255
  @root ||= documents.first.try(:_root)
274
256
  end
275
257
 
276
- # Get the root class for the enumerable.
277
- #
278
- # @example Get the root class.
279
- # context.root_class
280
- #
281
- # @return [ Class ] The root class.
282
258
  def root_class
283
259
  @root_class ||= root ? root.class : nil
284
260
  end
@@ -145,10 +145,40 @@ module Mongoid #:nodoc:
145
145
  #
146
146
  # @return [ Cursor ] An enumerable +Cursor+ of results.
147
147
  def execute
148
- criteria.inclusions.reject! do |metadata|
149
- metadata.eager_load(criteria)
148
+ collection, options = klass.collection, process_options
149
+ if criteria.inclusions.any?
150
+ collection.find(selector, options).entries.tap do |docs|
151
+ parent_ids = docs.map(&:id)
152
+ criteria.inclusions.reject! do |metadata|
153
+ if metadata.macro == :referenced_in
154
+ child_ids = load_ids(metadata.foreign_key)
155
+ metadata.eager_load(child_ids)
156
+ else
157
+ metadata.eager_load(parent_ids)
158
+ end
159
+ end
160
+ end
161
+ else
162
+ collection.find(selector, options)
150
163
  end
151
- klass.collection.find(selector, process_options) || []
164
+ end
165
+
166
+ # Loads an array of ids only for the current criteria. Used by eager
167
+ # loading to determine the documents to load.
168
+ #
169
+ # @example Load the related ids.
170
+ # criteria.load_ids("person_id")
171
+ #
172
+ # @param [ String ] key The id or foriegn key string.
173
+ #
174
+ # @return [ Array<String, BSON::ObjectId> ] The ids to load.
175
+ #
176
+ # @since 2.2.0
177
+ def load_ids(key)
178
+ klass.collection.driver.find(
179
+ selector,
180
+ process_options.merge({ :fields => { key => 1 }})
181
+ ).map { |doc| doc[key] }
152
182
  end
153
183
 
154
184
  # Return the first result for the +Context+.
@@ -31,7 +31,7 @@ module Mongoid #:nodoc:
31
31
  #
32
32
  # @return [ Document ] The new document.
33
33
  def initialize_copy(other)
34
- @attributes = other.as_document
34
+ other.as_document
35
35
  instance_variables.each { |name| remove_instance_variable(name) }
36
36
  COPYABLES.each do |name|
37
37
  value = other.instance_variable_get(name)
@@ -6,6 +6,7 @@ require "mongoid/criterion/exclusion"
6
6
  require "mongoid/criterion/inclusion"
7
7
  require "mongoid/criterion/inspection"
8
8
  require "mongoid/criterion/optional"
9
+ require "mongoid/criterion/scoping"
9
10
  require "mongoid/criterion/selector"
10
11
 
11
12
  module Mongoid #:nodoc:
@@ -29,6 +30,7 @@ module Mongoid #:nodoc:
29
30
  include Criterion::Inclusion
30
31
  include Criterion::Inspection
31
32
  include Criterion::Optional
33
+ include Criterion::Scoping
32
34
 
33
35
  attr_accessor \
34
36
  :documents,
@@ -253,10 +255,10 @@ module Mongoid #:nodoc:
253
255
  # scope for use with named scopes.
254
256
  #
255
257
  # @example Get the criteria as a scoped hash.
256
- # criteria.scoped
258
+ # criteria.as_conditions
257
259
  #
258
260
  # @return [ Hash ] The criteria as a scoped hash.
259
- def scoped
261
+ def as_conditions
260
262
  scope_options = @options.dup
261
263
  sorting = scope_options.delete(:sort)
262
264
  scope_options[:order_by] = sorting if sorting
@@ -165,7 +165,7 @@ module Mongoid #:nodoc:
165
165
  #
166
166
  # @since 2.2.1
167
167
  def from_map_or_db
168
- doc = IdentityMap.get(klass, extract_id)
168
+ doc = IdentityMap.get(klass, extract_id || selector)
169
169
  doc && doc.matches?(selector) ? doc : first
170
170
  end
171
171
 
@@ -228,21 +228,6 @@ module Mongoid #:nodoc:
228
228
  @inclusions ||= []
229
229
  end
230
230
 
231
- # Loads an array of ids only for the current criteria. Used by eager
232
- # loading to determine the documents to load.
233
- #
234
- # @example Load the related ids.
235
- # criteria.load_ids("person_id")
236
- #
237
- # @param [ String ] key The id or foriegn key string.
238
- #
239
- # @return [ Array<String, BSON::ObjectId> ] The ids to load.
240
- #
241
- # @since 2.2.0
242
- def load_ids(key)
243
- driver.find(selector, { :fields => { key => 1 }}).map { |doc| doc[key] }
244
- end
245
-
246
231
  # Adds a criterion to the +Criteria+ that specifies values to do
247
232
  # geospacial searches by. The field must be indexed with the "2d" option.
248
233
  #
@@ -15,8 +15,8 @@ module Mongoid #:nodoc:
15
15
  # @return [ Criteria ] The cloned criteria.
16
16
  def ascending(*fields)
17
17
  clone.tap do |crit|
18
- crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
19
- fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :asc ]) }
18
+ setup_sort_options(crit.options) unless fields.first.nil?
19
+ fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :asc ]) }
20
20
  end
21
21
  end
22
22
  alias :asc :ascending
@@ -56,8 +56,8 @@ module Mongoid #:nodoc:
56
56
  # @return [ Criteria ] The cloned criteria.
57
57
  def descending(*fields)
58
58
  clone.tap do |crit|
59
- crit.options[:sort] = [] unless options[:sort] || fields.first.nil?
60
- fields.flatten.each { |field| merge_options(crit.options[:sort], [ field, :desc ]) }
59
+ setup_sort_options(crit.options) unless fields.first.nil?
60
+ fields.flatten.each { |field| merge_options(crit.options[:sort], [ localize(field), :desc ]) }
61
61
  end
62
62
  end
63
63
  alias :desc :descending
@@ -89,11 +89,12 @@ module Mongoid #:nodoc:
89
89
  #
90
90
  # @return [ Criteria ] The cloned criteria.
91
91
  def for_ids(*ids)
92
+ field = klass.fields["_id"]
92
93
  ids.flatten!
93
94
  if ids.size > 1
94
- where(:_id.in => ::BSON::ObjectId.convert(klass, ids))
95
+ any_in(:_id => ids.map{ |id| field.serialize(id) })
95
96
  else
96
- where(:_id => ids.first)
97
+ where(:_id => field.serialize(ids.first))
97
98
  end
98
99
  end
99
100
 
@@ -135,7 +136,7 @@ module Mongoid #:nodoc:
135
136
  def order_by(*args)
136
137
  clone.tap do |crit|
137
138
  arguments = args.size == 1 ? args.first : args
138
- crit.options[:sort] = [] unless options[:sort] || args.first.nil?
139
+ setup_sort_options(crit.options) unless args.first.nil?
139
140
  if arguments.is_a?(Array)
140
141
  #[:name, :asc]
141
142
  if arguments.size == 2 && (arguments.first.is_a?(Symbol) || arguments.first.is_a?(String))
@@ -198,12 +199,12 @@ module Mongoid #:nodoc:
198
199
  "due to the fact that hash doesn't have order this may cause unpredictable results"
199
200
  end
200
201
  arguments.each_pair do |field, direction|
201
- merge_options(crit.options[:sort], [ field, direction ])
202
+ merge_options(crit.options[:sort], [ localize(field), direction ])
202
203
  end
203
204
  when Array
204
- merge_options(crit.options[:sort],arguments)
205
+ merge_options(crit.options[:sort], arguments.map{ |field| localize(field) })
205
206
  when Complex
206
- merge_options(crit.options[:sort], [ arguments.key, arguments.operator.to_sym ])
207
+ merge_options(crit.options[:sort], [ localize(arguments.key), arguments.operator.to_sym ])
207
208
  end
208
209
  end
209
210
 
@@ -227,6 +228,32 @@ module Mongoid #:nodoc:
227
228
  options << new_option.flatten
228
229
  end
229
230
  end
231
+
232
+ # Initialize the sort options
233
+ # Set options[:sort] to an empty array if it does not exist, or dup it if
234
+ # it already has been defined
235
+ #
236
+ # @example criteria.setup_sort_options(crit.options)
237
+ #
238
+ # @param [ Array<Array> ] Existing options
239
+ #
240
+ # @since 2.4.0
241
+ def setup_sort_options(options)
242
+ options[:sort] = options[:sort] ? options[:sort].dup : []
243
+ end
244
+
245
+ # Check if field is localized and return localized version if it is.
246
+ #
247
+ # @example localize
248
+ # criteria.localize(:description)
249
+ #
250
+ # @param [ <Symbol> ] field to localize
251
+ def localize(field)
252
+ if klass.fields[field.to_s].try(:localized?)
253
+ field = "#{field}.#{::I18n.locale}".to_sym
254
+ end
255
+ field
256
+ end
230
257
  end
231
258
  end
232
259
  end
@@ -0,0 +1,83 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Criterion #:nodoc:
4
+ module Scoping
5
+
6
+ attr_accessor :default_scopable
7
+
8
+ # Apply the model's default scope to this criteria.
9
+ #
10
+ # @example Apply the default scope.
11
+ # criteria.apply_default_scope
12
+ #
13
+ # @return [ Criteria ] The criteria.
14
+ #
15
+ # @since 2.4.0
16
+ def apply_default_scope
17
+ if klass.default_scoping && default_scopable?
18
+ self.default_scopable = false
19
+ fuse(klass.default_scoping)
20
+ else
21
+ self
22
+ end
23
+ end
24
+
25
+ # Is the default scope of the class allowed to be applied?
26
+ #
27
+ # @example Can the default scope be applied?
28
+ # criteria.default_scopable?
29
+ #
30
+ # @return [ true, false ] The the default can be applied.
31
+ #
32
+ # @since 2.4.0
33
+ def default_scopable?
34
+ default_scopable != false
35
+ end
36
+
37
+ # Force the default scope to be applied to the criteria.
38
+ #
39
+ # @example Force default scoping.
40
+ # criteria.scoped
41
+ #
42
+ # @return [ Criteria ] The criteria.
43
+ #
44
+ # @since 2.4.0
45
+ def scoped
46
+ self.default_scopable = true
47
+ apply_default_scope
48
+ end
49
+
50
+ # Get the criteria with the default scoping removed.
51
+ #
52
+ # @note This has slightly different behaviour than AR - will remove the
53
+ # default scoping if no other criteria have been chained and tampered
54
+ # with the criterion instead of clearing everything.
55
+ #
56
+ # @example Get the criteria unscoped.
57
+ # criteria.unscoped
58
+ #
59
+ # @return [ Criteria ] The unscoped criteria.
60
+ #
61
+ # @since 2.4.0
62
+ def unscoped
63
+ clone.tap do |criteria|
64
+ criteria.clear_scoping
65
+ criteria.default_scopable = false
66
+ end
67
+ end
68
+
69
+ # Remove all scoping from the criteria.
70
+ #
71
+ # @example Remove the default scope.
72
+ # criteria.clear_scoping
73
+ #
74
+ # @return [ nil ] No guaranteed return value.
75
+ #
76
+ # @since 2.4.0
77
+ def clear_scoping
78
+ selector.clear
79
+ options.clear
80
+ end
81
+ end
82
+ end
83
+ end