mongoid 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/Rakefile +4 -4
  2. data/lib/config/locales/{pt-br.yml → pt-BR.yml} +5 -5
  3. data/lib/config/locales/ru.yml +1 -1
  4. data/lib/config/locales/zh-CN.yml +2 -0
  5. data/lib/mongoid.rb +0 -1
  6. data/lib/mongoid/attributes.rb +9 -6
  7. data/lib/mongoid/collection.rb +21 -0
  8. data/lib/mongoid/config.rb +31 -8
  9. data/lib/mongoid/config/replset_database.rb +32 -2
  10. data/lib/mongoid/contexts.rb +0 -1
  11. data/lib/mongoid/contexts/enumerable.rb +73 -36
  12. data/lib/mongoid/contexts/mongo.rb +5 -12
  13. data/lib/mongoid/copyable.rb +2 -2
  14. data/lib/mongoid/criteria.rb +4 -23
  15. data/lib/mongoid/criterion/exclusion.rb +15 -0
  16. data/lib/mongoid/criterion/inclusion.rb +1 -1
  17. data/lib/mongoid/criterion/optional.rb +0 -1
  18. data/lib/mongoid/criterion/unconvertable.rb +20 -0
  19. data/lib/mongoid/cursor.rb +3 -3
  20. data/lib/mongoid/dirty.rb +8 -8
  21. data/lib/mongoid/document.rb +33 -36
  22. data/lib/mongoid/extensions.rb +7 -0
  23. data/lib/mongoid/extensions/object/checks.rb +32 -0
  24. data/lib/mongoid/extensions/object/conversions.rb +1 -1
  25. data/lib/mongoid/extensions/object_id/conversions.rb +6 -1
  26. data/lib/mongoid/extensions/range/conversions.rb +25 -0
  27. data/lib/mongoid/factory.rb +27 -10
  28. data/lib/mongoid/field.rb +50 -0
  29. data/lib/mongoid/fields.rb +42 -7
  30. data/lib/mongoid/finders.rb +5 -17
  31. data/lib/mongoid/identity.rb +1 -1
  32. data/lib/mongoid/inspection.rb +17 -21
  33. data/lib/mongoid/matchers.rb +6 -2
  34. data/lib/mongoid/matchers/strategies.rb +2 -2
  35. data/lib/mongoid/named_scope.rb +1 -1
  36. data/lib/mongoid/observer.rb +45 -14
  37. data/lib/mongoid/paranoia.rb +2 -2
  38. data/lib/mongoid/persistence.rb +2 -2
  39. data/lib/mongoid/persistence/update.rb +2 -1
  40. data/lib/mongoid/railtie.rb +3 -5
  41. data/lib/mongoid/relations.rb +1 -0
  42. data/lib/mongoid/relations/builders.rb +3 -3
  43. data/lib/mongoid/relations/builders/embedded/in.rb +1 -1
  44. data/lib/mongoid/relations/builders/embedded/many.rb +1 -1
  45. data/lib/mongoid/relations/builders/embedded/one.rb +1 -2
  46. data/lib/mongoid/relations/builders/referenced/in.rb +0 -3
  47. data/lib/mongoid/relations/builders/referenced/many.rb +21 -1
  48. data/lib/mongoid/relations/builders/referenced/one.rb +0 -4
  49. data/lib/mongoid/relations/embedded/many.rb +1 -17
  50. data/lib/mongoid/relations/macros.rb +3 -2
  51. data/lib/mongoid/relations/many.rb +2 -0
  52. data/lib/mongoid/relations/proxy.rb +1 -1
  53. data/lib/mongoid/relations/referenced/batch.rb +71 -0
  54. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  55. data/lib/mongoid/relations/referenced/many.rb +61 -2
  56. data/lib/mongoid/serialization.rb +1 -1
  57. data/lib/mongoid/validations/uniqueness.rb +1 -1
  58. data/lib/mongoid/version.rb +1 -1
  59. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +8 -11
  60. metadata +22 -64
  61. data/lib/mongoid/contexts/paging.rb +0 -50
data/Rakefile CHANGED
@@ -24,19 +24,19 @@ task :release => :build do
24
24
  system "gem push mongoid-#{Mongoid::VERSION}.gem"
25
25
  end
26
26
 
27
- Rspec::Core::RakeTask.new(:spec) do |spec|
27
+ RSpec::Core::RakeTask.new(:spec) do |spec|
28
28
  spec.pattern = "spec/**/*_spec.rb"
29
29
  end
30
30
 
31
- Rspec::Core::RakeTask.new("spec:unit") do |spec|
31
+ RSpec::Core::RakeTask.new("spec:unit") do |spec|
32
32
  spec.pattern = "spec/unit/**/*_spec.rb"
33
33
  end
34
34
 
35
- Rspec::Core::RakeTask.new("spec:functional") do |spec|
35
+ RSpec::Core::RakeTask.new("spec:functional") do |spec|
36
36
  spec.pattern = "spec/functional/**/*_spec.rb"
37
37
  end
38
38
 
39
- Rspec::Core::RakeTask.new('spec:progress') do |spec|
39
+ RSpec::Core::RakeTask.new('spec:progress') do |spec|
40
40
  spec.rspec_opts = %w(--format progress)
41
41
  spec.pattern = "spec/**/*_spec.rb"
42
42
  end
@@ -1,4 +1,4 @@
1
- pt-br:
1
+ pt-BR:
2
2
  mongoid:
3
3
  errors:
4
4
  messages:
@@ -12,7 +12,7 @@ pt-br:
12
12
  O campo foi definido como %{klass}, mas recebeu uma instância de %{other} com
13
13
  o valor %{value}.
14
14
  unsupported_version:
15
- MongoDB %{version} não é suportada, por favor atualize para a
15
+ MongoDB %{version} não é suportada, por favor atualize para a
16
16
  versão %{mongo_version}.
17
17
  validations:
18
18
  A validação falhou - %{errors}.
@@ -22,7 +22,7 @@ pt-br:
22
22
  do documento raiz.
23
23
  invalid_field:
24
24
  Não é permitido definir um campo com o nome %{name}. Não defina
25
- campos que entrem em conflito com os nomes dos atributos internos e métodos
25
+ campos que entrem em conflito com os nomes dos atributos internos e métodos
26
26
  do Mongoid. Use Document#instance_methods para consultar esses nomes.
27
27
  too_many_nested_attribute_records:
28
28
  A aceitação de atributos encadeados para %{association} encontra-se limitada
@@ -36,5 +36,5 @@ pt-br:
36
36
  A definição de inverse_of nesta associação não é permitida. Apenas
37
37
  use esta opção em embedded_in ou references_many as array.
38
38
  unsaved_document:
39
- You cannot call create or create! through a relational association
40
- relation (%{document}) who's parent (%{base}) is not already saved.
39
+ Você não pode chamar os métodos create ou create! de uma associação
40
+ relacional (%{document}) cujo pai (%{base}) ainda não foi salvo.
@@ -7,7 +7,7 @@ ru:
7
7
  document_not_found:
8
8
  Документ класса %{klass} с id %{identifiers} не найден.
9
9
  invalid_database:
10
- База данных должная быть Mongo::DB, а не %{name}.
10
+ База данных должна быть Mongo::DB, а не %{name}.
11
11
  invalid_type:
12
12
  Поле уже было определено в классе %{klass}, но получено как %{other}
13
13
  со значением %{value}.
@@ -2,6 +2,8 @@ zh-CN:
2
2
  mongoid:
3
3
  errors:
4
4
  messages:
5
+ blank:
6
+ 不能为空
5
7
  taken:
6
8
  已占用
7
9
  document_not_found:
@@ -37,7 +37,6 @@ require "active_model/serialization"
37
37
  require "active_model/translation"
38
38
  require "active_model/validator"
39
39
  require "active_model/validations"
40
- require "will_paginate/collection"
41
40
  require "mongo"
42
41
  require "mongoid/errors"
43
42
  require "mongoid/extensions"
@@ -8,6 +8,9 @@ module Mongoid #:nodoc:
8
8
  module Attributes
9
9
  include Processing
10
10
 
11
+ attr_reader :attributes
12
+ alias :raw_attributes :attributes
13
+
11
14
  # Determine if an attribute is present.
12
15
  #
13
16
  # @example Is the attribute present?
@@ -38,7 +41,7 @@ module Mongoid #:nodoc:
38
41
  # @since 1.0.0
39
42
  def read_attribute(name)
40
43
  access = name.to_s
41
- value = @attributes[access]
44
+ value = attributes[access]
42
45
  accessed(access, value)
43
46
  end
44
47
  alias :[] :read_attribute
@@ -54,7 +57,7 @@ module Mongoid #:nodoc:
54
57
  # @since 1.0.0
55
58
  def remove_attribute(name)
56
59
  access = name.to_s
57
- modify(access, @attributes.delete(access), nil)
60
+ modify(access, attributes.delete(access), nil)
58
61
  end
59
62
 
60
63
  # Override respond_to? so it responds properly for dynamic attributes.
@@ -69,8 +72,8 @@ module Mongoid #:nodoc:
69
72
  # @since 1.0.0
70
73
  def respond_to?(*args)
71
74
  (Mongoid.allow_dynamic_fields &&
72
- @attributes &&
73
- @attributes.has_key?(args.first.to_s)
75
+ attributes &&
76
+ attributes.has_key?(args.first.to_s)
74
77
  ) || super
75
78
  end
76
79
 
@@ -90,7 +93,7 @@ module Mongoid #:nodoc:
90
93
  # @since 1.0.0
91
94
  def write_attribute(name, value)
92
95
  access = name.to_s
93
- modify(access, @attributes[access], typed_value_for(access, value))
96
+ modify(access, attributes[access], typed_value_for(access, value))
94
97
  end
95
98
  alias :[]= :write_attribute
96
99
 
@@ -156,7 +159,7 @@ module Mongoid #:nodoc:
156
159
  # @param [ Array ] *args The arguments to the method.
157
160
  def method_missing(name, *args)
158
161
  attr = name.to_s
159
- return super unless @attributes.has_key?(attr.reader)
162
+ return super unless attributes.has_key?(attr.reader)
160
163
  if attr.writer?
161
164
  write_attribute(attr.reader, (args.size > 1) ? args : args.first)
162
165
  else
@@ -83,6 +83,27 @@ module Mongoid #:nodoc
83
83
  @klass, @name = klass, name
84
84
  end
85
85
 
86
+ # Inserts one or more documents in the collection.
87
+ #
88
+ # @example Insert documents.
89
+ # collection.insert(
90
+ # { "field" => "value" },
91
+ # :safe => true
92
+ # )
93
+ #
94
+ # @param [ Hash, Array<Hash> ] documents A single document or multiples.
95
+ # @param [ Hash ] options The options.
96
+ #
97
+ # @since 2.0.2, batch-relational-insert
98
+ def insert(documents, options = {})
99
+ inserter = Thread.current[:mongoid_batch_insert]
100
+ if inserter
101
+ inserter.consume(documents, options)
102
+ else
103
+ master.insert(documents, options)
104
+ end
105
+ end
106
+
86
107
  # Perform a map/reduce on the documents.
87
108
  #
88
109
  # @example Perform the map/reduce.
@@ -111,7 +111,7 @@ module Mongoid #:nodoc
111
111
  options.except("database", "slaves", "databases").each_pair do |name, value|
112
112
  send("#{name}=", value) if respond_to?("#{name}=")
113
113
  end
114
- configure_databases(options)
114
+ @master, @slaves = configure_databases(options)
115
115
  configure_extras(options["databases"])
116
116
  end
117
117
 
@@ -132,14 +132,25 @@ module Mongoid #:nodoc
132
132
  end
133
133
  end
134
134
 
135
+ # Returns the default logger, which is either a Rails logger of stdout logger
136
+ #
137
+ # @example Get the default logger
138
+ # config.default_logger
139
+ #
140
+ # @return [ Logger ] The default Logger instance.
141
+ def default_logger
142
+ defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
143
+ end
144
+
135
145
  # Returns the logger, or defaults to Rails logger or stdout logger.
136
146
  #
137
147
  # @example Get the logger.
138
148
  # config.logger
139
149
  #
140
- # @return [ Logger ] The desired logger.
150
+ # @return [ Logger ] The configured logger or a default Logger instance.
141
151
  def logger
142
- @logger ||= defined?(Rails) ? Rails.logger : ::Logger.new($stdout)
152
+ @logger = default_logger unless defined?(@logger)
153
+ @logger
143
154
  end
144
155
 
145
156
  # Sets the logger for Mongoid to use.
@@ -152,6 +163,18 @@ module Mongoid #:nodoc
152
163
  @logger = logger
153
164
  end
154
165
 
166
+ # Purge all data in all collections, including indexes.
167
+ #
168
+ # @example Purge all data.
169
+ # Mongoid::Config.purge!
170
+ #
171
+ # @since 2.0.2
172
+ def purge!
173
+ master.collections.map do |collection|
174
+ collection.drop if collection.name !~ /system/
175
+ end
176
+ end
177
+
155
178
  # Sets whether the times returned from the database use the ruby or
156
179
  # the ActiveSupport time zone.
157
180
  # If you omit this setting, then times will use the ruby time zone.
@@ -209,7 +232,7 @@ module Mongoid #:nodoc
209
232
  # @return [ Mongo::DB ] The master database.
210
233
  def master
211
234
  unless @master
212
- configure_databases(@settings) unless @settings.blank?
235
+ @master, @slaves = configure_databases(@settings) unless @settings.blank?
213
236
  raise Errors::InvalidDatabase.new(nil) unless @master
214
237
  end
215
238
  if @reconnect
@@ -272,7 +295,7 @@ module Mongoid #:nodoc
272
295
  # @return [ Array<Mongo::DB>, nil ] The slave databases.
273
296
  def slaves
274
297
  unless @slaves
275
- configure_databases(@settings) if @settings && @settings[:database]
298
+ @master, @slaves = configure_databases(@settings) if @settings && @settings[:database]
276
299
  end
277
300
  @slaves
278
301
  end
@@ -314,9 +337,9 @@ module Mongoid #:nodoc
314
337
  # @since 2.0.0.rc.1
315
338
  def configure_databases(options)
316
339
  if options.has_key?('hosts')
317
- @master, @slaves = ReplsetDatabase.new(options).configure
340
+ ReplsetDatabase.new(options).configure
318
341
  else
319
- @master, @slaves = Database.new(options).configure
342
+ Database.new(options).configure
320
343
  end
321
344
  end
322
345
 
@@ -331,7 +354,7 @@ module Mongoid #:nodoc
331
354
  def configure_extras(extras)
332
355
  @databases = (extras || []).inject({}) do |dbs, (name, options)|
333
356
  dbs.tap do |extra|
334
- dbs[name], dbs["#{name}_slaves"] = Database.new(options).configure
357
+ dbs[name], dbs["#{name}_slaves"] = configure_databases(options)
335
358
  end
336
359
  end
337
360
  end
@@ -17,8 +17,38 @@ module Mongoid #:nodoc:
17
17
  #yes, construction is weird but the driver wants "A list of host-port pairs ending with a hash containing any options"
18
18
  #mongo likes symbols
19
19
  options = self.inject({}) { |memo, (k, v)| memo[k.to_sym] = v; memo}
20
- connection = Mongo::ReplSetConnection.new(*(self['hosts'] << options))
21
- [ connection.db(self['database']), nil ]
20
+ connection = Mongo::ReplSetConnection.new(*(hosts << options))
21
+
22
+ if authenticating?
23
+ connection.add_auth(database, username, password)
24
+ connection.apply_saved_authentication
25
+ end
26
+
27
+ [ connection.db(database), nil ]
28
+ end
29
+
30
+ # Do we need to authenticate against the database?
31
+ #
32
+ # @example Are we authenticating?
33
+ # db.authenticating?
34
+ #
35
+ # @return [ true, false ] True if auth is needed, false if not.
36
+ #
37
+ # @since 2.0.2
38
+ def authenticating?
39
+ username || password
40
+ end
41
+
42
+ # Convenience for accessing the hash via dot notation.
43
+ #
44
+ # @example Access a value in alternate syntax.
45
+ # db.host
46
+ #
47
+ # @return [ Object ] The value in the hash.
48
+ #
49
+ # @since 2.0.2
50
+ def method_missing(name, *args, &block)
51
+ self[name.to_s]
22
52
  end
23
53
 
24
54
  # Create the new db configuration class.
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
- require "mongoid/contexts/paging"
3
2
  require "mongoid/contexts/enumerable"
4
3
  require "mongoid/contexts/mongo"
5
4
 
@@ -4,7 +4,6 @@ require 'mongoid/contexts/enumerable/sort'
4
4
  module Mongoid #:nodoc:
5
5
  module Contexts #:nodoc:
6
6
  class Enumerable
7
- include Paging
8
7
  include Relations::Embedded::Atomic
9
8
 
10
9
  attr_accessor :collection, :criteria
@@ -15,30 +14,33 @@ module Mongoid #:nodoc:
15
14
  # Return aggregation counts of the grouped documents. This will count by
16
15
  # the first field provided in the fields array.
17
16
  #
18
- # Returns:
17
+ # @example Aggregate on a field.
18
+ # person.addresses.only(:street).aggregate
19
19
  #
20
- # A +Hash+ with field values as keys, count as values
20
+ # @return [ Hash ] Field values as keys, count as values
21
21
  def aggregate
22
- counts = {}
23
- group.each_pair { |key, value| counts[key] = value.size }
24
- counts
22
+ {}.tap do |counts|
23
+ group.each_pair { |key, value| counts[key] = value.size }
24
+ end
25
25
  end
26
26
 
27
27
  # Get the average value for the supplied field.
28
28
  #
29
- # Example:
30
- #
31
- # <tt>context.avg(:age)</tt>
32
- #
33
- # Returns:
29
+ # @example Get the average.
30
+ # context.avg(:age)
34
31
  #
35
- # A numeric value that is the average.
32
+ # @return [ Numeric ] A numeric value that is the average.
36
33
  def avg(field)
37
34
  total = sum(field)
38
35
  total ? (total.to_f / count) : nil
39
36
  end
40
37
 
41
38
  # Gets the number of documents in the array. Delegates to size.
39
+ #
40
+ # @example Get the count.
41
+ # context.count
42
+ #
43
+ # @return [ Integer ] The count of documents.
42
44
  def count
43
45
  @count ||= filter.size
44
46
  end
@@ -78,9 +80,10 @@ module Mongoid #:nodoc:
78
80
  # Gets an array of distinct values for the supplied field across the
79
81
  # entire array or the susbset given the criteria.
80
82
  #
81
- # Example:
83
+ # @example Get the list of distinct values.
84
+ # context.distinct(:title)
82
85
  #
83
- # <tt>context.distinct(:title)</tt>
86
+ # @return [ Array<String> ] The distinct values.
84
87
  def distinct(field)
85
88
  execute.collect { |doc| doc.send(field) }.uniq
86
89
  end
@@ -88,18 +91,20 @@ module Mongoid #:nodoc:
88
91
  # Enumerable implementation of execute. Returns matching documents for
89
92
  # the selector, and adds options if supplied.
90
93
  #
91
- # Returns:
94
+ # @example Execute the context.
95
+ # context.execute
92
96
  #
93
- # An +Array+ of documents that matched the selector.
94
- def execute(paginating = false)
97
+ # @return [ Array<Document> ] Documents that matched the selector.
98
+ def execute
95
99
  limit(sort(filter)) || []
96
100
  end
97
101
 
98
102
  # Groups the documents by the first field supplied in the field options.
99
103
  #
100
- # Returns:
104
+ # @example Group the context.
105
+ # context.group
101
106
  #
102
- # A +Hash+ with field values as keys, arrays of documents as values.
107
+ # @return [ Hash ] Field values as keys, arrays of documents as values.
103
108
  def group
104
109
  field = field_list.first
105
110
  execute.group_by { |doc| doc.send(field) }
@@ -109,9 +114,10 @@ module Mongoid #:nodoc:
109
114
  # options from a +Criteria+ and a documents array that is the underlying
110
115
  # array of embedded documents from a has many association.
111
116
  #
112
- # Example:
117
+ # @example Create a new context.
118
+ # Mongoid::Contexts::Enumerable.new(criteria)
113
119
  #
114
- # <tt>Mongoid::Contexts::Enumerable.new(criteria)</tt>
120
+ # @param [ Criteria ] criteria The criteria for the context.
115
121
  def initialize(criteria)
116
122
  @criteria = criteria
117
123
  end
@@ -119,44 +125,47 @@ module Mongoid #:nodoc:
119
125
  # Iterate over each +Document+ in the results. This can take an optional
120
126
  # block to pass to each argument in the results.
121
127
  #
122
- # Example:
123
- #
124
- # <tt>context.iterate { |doc| p doc }</tt>
128
+ # @example Iterate over the documents.
129
+ # context.iterate { |doc| p doc }
125
130
  def iterate(&block)
126
131
  execute.each(&block)
127
132
  end
128
133
 
129
134
  # Get the largest value for the field in all the documents.
130
135
  #
131
- # Returns:
136
+ # @example Get the max value.
137
+ # context.max(:age)
132
138
  #
133
- # The numerical largest value.
139
+ # @return [ Numeric ] The numerical largest value.
134
140
  def max(field)
135
141
  determine(field, :>=)
136
142
  end
137
143
 
138
144
  # Get the smallest value for the field in all the documents.
139
145
  #
140
- # Returns:
146
+ # @example Get the minimum value.
147
+ # context.min(:age)
141
148
  #
142
- # The numerical smallest value.
149
+ # @return [ Numeric ] The numerical smallest value.
143
150
  def min(field)
144
151
  determine(field, :<=)
145
152
  end
146
153
 
147
154
  # Get one document.
148
155
  #
149
- # Returns:
156
+ # @example Get one document.
157
+ # context.one
150
158
  #
151
- # The first document in the +Array+
159
+ # @return [ Document ] The first document in the array.
152
160
  alias :one :first
153
161
 
154
162
  # Get one document and tell the criteria to skip this record on
155
163
  # successive calls.
156
164
  #
157
- # Returns:
165
+ # @example Shift the documents.
166
+ # context.shift
158
167
  #
159
- # The first document in the +Array+
168
+ # @return [ Document ] The first document in the array.
160
169
  def shift
161
170
  first.tap do |document|
162
171
  self.criteria = criteria.skip((options[:skip] || 0) + 1)
@@ -165,12 +174,13 @@ module Mongoid #:nodoc:
165
174
 
166
175
  # Get the sum of the field values for all the documents.
167
176
  #
168
- # Returns:
177
+ # @example Get the sum of the field.
178
+ # context.sum(:cost)
169
179
  #
170
- # The numerical sum of all the document field values.
180
+ # @return [ Numeric ] The numerical sum of all the document field values.
171
181
  def sum(field)
172
182
  sum = execute.inject(nil) do |memo, doc|
173
- value = doc.send(field)
183
+ value = doc.send(field) || 0
174
184
  memo ? memo += value : value
175
185
  end
176
186
  end
@@ -193,20 +203,36 @@ module Mongoid #:nodoc:
193
203
  alias :update :update_all
194
204
 
195
205
  protected
206
+
196
207
  # Filters the documents against the criteria's selector
208
+ #
209
+ # @example Filter the documents.
210
+ # context.filter
211
+ #
212
+ # @return [ Array ] The documents filtered.
197
213
  def filter
198
214
  documents.select { |document| document.matches?(selector) }
199
215
  end
200
216
 
201
217
  # If the field exists, perform the comparison and set if true.
218
+ #
219
+ # @example Compare.
220
+ # context.determine
221
+ #
222
+ # @return [ Array<Document> ] The matching documents.
202
223
  def determine(field, operator)
203
224
  matching = documents.inject(nil) do |memo, doc|
204
- value = doc.send(field)
225
+ value = doc.send(field) || 0
205
226
  (memo && memo.send(operator, value)) ? memo : value
206
227
  end
207
228
  end
208
229
 
209
230
  # Limits the result set if skip and limit options.
231
+ #
232
+ # @example Limit the results.
233
+ # context.limit(documents)
234
+ #
235
+ # @return [ Array<Document> ] The limited documents.
210
236
  def limit(documents)
211
237
  skip, limit = options[:skip], options[:limit]
212
238
  if skip && limit
@@ -219,12 +245,23 @@ module Mongoid #:nodoc:
219
245
  documents
220
246
  end
221
247
 
248
+ # Set the collection to the collection of the root document.
249
+ #
250
+ # @example Set the collection.
251
+ # context.set_collection
252
+ #
253
+ # @return [ Collection ] The root collection.
222
254
  def set_collection
223
255
  root = documents.first._root
224
256
  @collection = root.collection if root && !root.embedded?
225
257
  end
226
258
 
227
259
  # Sorts the result set if sort options have been set.
260
+ #
261
+ # @example Sort the documents.
262
+ # context.sort(documents)
263
+ #
264
+ # @return [ Array<Document> ] The sorted documents.
228
265
  def sort(documents)
229
266
  return documents if options[:sort].blank?
230
267
  documents.sort_by do |document|