mongoid 2.0.0.rc.4 → 2.0.0.rc.5

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.
@@ -218,7 +218,7 @@ module Mongoid #:nodoc:
218
218
  if value.is_a?(Hash)
219
219
  metadata.nested_builder(value, {}).build(self)
220
220
  else
221
- send("#{name}=", value, :building => true)
221
+ send("#{name}=", value, :binding => true)
222
222
  end
223
223
  end
224
224
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "uri"
3
3
  require "mongoid/config/database"
4
+ require "mongoid/config/replset_database"
4
5
 
5
6
  module Mongoid #:nodoc
6
7
 
@@ -42,6 +43,7 @@ module Mongoid #:nodoc
42
43
  option :autocreate_indexes, :default => false
43
44
  option :skip_version_check, :default => false
44
45
  option :time_zone, :default => nil
46
+ option :binding_defaults, :default => { :binding => false, :continue => true }
45
47
 
46
48
  # Adds a new I18n locale file to the load path.
47
49
  #
@@ -56,7 +58,7 @@ module Mongoid #:nodoc
56
58
  Dir[
57
59
  File.join(
58
60
  File.dirname(__FILE__), "..", "config", "locales", "#{language_code}.yml"
59
- )
61
+ )
60
62
  ].each do |file|
61
63
  I18n.load_path << File.expand_path(file)
62
64
  end
@@ -315,7 +317,11 @@ module Mongoid #:nodoc
315
317
  #
316
318
  # @since 2.0.0.rc.1
317
319
  def configure_databases(options)
318
- @master, @slaves = Database.new(options).configure
320
+ if options.has_key?('hosts')
321
+ @master, @slaves = ReplsetDatabase.new(options).configure
322
+ else
323
+ @master, @slaves = Database.new(options).configure
324
+ end
319
325
  end
320
326
 
321
327
  # Get the secondary databases from settings.
@@ -329,7 +335,7 @@ module Mongoid #:nodoc
329
335
  def configure_extras(extras)
330
336
  @databases = (extras || []).inject({}) do |dbs, (name, options)|
331
337
  dbs.tap do |extra|
332
- dbs[name], dbs["#{name}_slaves"] = Database.new(options).configure
338
+ dbs[name], dbs["#{name}_slaves"] = Database.new(options).configure
333
339
  end
334
340
  end
335
341
  end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Config #:nodoc:
4
+ class ReplsetDatabase < Hash
5
+
6
+ # Configure the database connections. This will return an array
7
+ # containing one Mongo::DB and nil (to keep compatibility with Mongoid::Config::Database)
8
+ # If you want the reads to go to a secondary node use the :read_secondary(true): option
9
+ #
10
+ # @example Configure the connection.
11
+ # db.configure
12
+ #
13
+ # @return [ Array<Mongo::DB, nil ] The Mongo databases.
14
+ #
15
+ # @since 2.0.0.rc.5
16
+ def configure
17
+ #yes, construction is weird but the driver wants "A list of host-port pairs ending with a hash containing any options"
18
+ #mongo likes symbols
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 ]
22
+ end
23
+
24
+ # Create the new db configuration class.
25
+ #
26
+ # @example Initialize the class.
27
+ # Config::ReplsetDatabase.new(
28
+ # "hosts" => [[host1,port1],[host2,port2]]
29
+ # )
30
+ #
31
+ # replSet does not supports auth
32
+ #
33
+ # @param [ Hash ] options The configuration options.
34
+ #
35
+ # @option options [ Array ] :hosts The database host.
36
+ # @option options [ String ] :database The database name.
37
+ # @option options [ Boolean ] :read_secondary Tells the driver to read from secondaries.
38
+ # ...
39
+ #
40
+ # @see Mongo::ReplSetConnection for all options
41
+ #
42
+ # @since 2.0.0.rc.5
43
+ def initialize(options = {})
44
+ merge!(options)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -145,8 +145,8 @@ module Mongoid #:nodoc:
145
145
  # @param [ Hash ] attributes The attributes to create with.
146
146
  #
147
147
  # @return [ Document ] The newly created document.
148
- def create(attributes = {})
149
- new(attributes).tap(&:save)
148
+ def create(attributes = {}, &block)
149
+ new(attributes, &block).tap(&:save)
150
150
  end
151
151
 
152
152
  # Create a new document. This will instantiate a new document and
@@ -160,8 +160,8 @@ module Mongoid #:nodoc:
160
160
  # @param [ Hash ] attributes The attributes to create with.
161
161
  #
162
162
  # @return [ Document ] The newly created document.
163
- def create!(attributes = {})
164
- document = new(attributes)
163
+ def create!(attributes = {}, &block)
164
+ document = new(attributes, &block)
165
165
  fail_validate!(document) if document.insert.errors.any?
166
166
  document
167
167
  end
@@ -25,7 +25,7 @@ module Mongoid # :nodoc:
25
25
  def build(name, object, metadata, options = {})
26
26
  relation = create_relation(object, metadata)
27
27
  set(name, relation).tap do |relation|
28
- relation.bind(options) if relation
28
+ relation.load!(options) if relation && options[:eager]
29
29
  end
30
30
  end
31
31
 
@@ -39,10 +39,8 @@ module Mongoid # :nodoc:
39
39
  # @return [ Hash ] The options.
40
40
  #
41
41
  # @since 2.0.0.rc.1
42
- def configurables(args)
43
- options = args.extract_options!
44
- options.merge!(:building => false) unless options[:building] == true
45
- { :building => true, :continue => true }.merge(options)
42
+ def options(args)
43
+ Mongoid.binding_defaults.merge(args.extract_options!)
46
44
  end
47
45
 
48
46
  # Create a relation from an object and metadata.
@@ -111,11 +109,16 @@ module Mongoid # :nodoc:
111
109
  tap do
112
110
  define_method(name) do |*args|
113
111
  reload, variable = args.first, "@#{name}"
114
- options = configurables(args)
112
+ options = options(args)
115
113
  if instance_variable_defined?(variable) && !reload
116
114
  instance_variable_get(variable)
117
115
  else
118
- build(name, @attributes[metadata.key], metadata, options)
116
+ build(
117
+ name,
118
+ @attributes[metadata.key],
119
+ metadata,
120
+ options.merge(:binding => true, :eager => metadata.embedded?)
121
+ )
119
122
  end
120
123
  end
121
124
  end
@@ -138,12 +141,12 @@ module Mongoid # :nodoc:
138
141
  def setter(name, metadata)
139
142
  tap do
140
143
  define_method("#{name}=") do |*args|
141
- object, options = args.first, configurables(args)
144
+ object, options = args.first, options(args)
142
145
  variable = "@#{name}"
143
146
  if relation_exists?(name)
144
147
  set(name, ivar(name).substitute(object, options))
145
148
  else
146
- build(name, object, metadata, options)
149
+ build(name, object, metadata, options.merge(:eager => true))
147
150
  end
148
151
  end
149
152
  end
@@ -6,6 +6,8 @@ module Mongoid # :nodoc:
6
6
  class Binding
7
7
  attr_reader :base, :target, :metadata
8
8
 
9
+ OPTIONS = { :binding => true, :continue => false }
10
+
9
11
  # Create the new binding.
10
12
  #
11
13
  # @example Initialize a binding.
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The binding options.
21
21
  #
22
22
  # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -32,14 +32,14 @@ module Mongoid # :nodoc:
32
32
  target.do_or_do_not(
33
33
  inverse,
34
34
  false,
35
- :building => true,
35
+ :binding => true,
36
36
  :continue => false
37
- ).push(base, :building => true, :continue => false)
37
+ ).push(base, :binding => true, :continue => false)
38
38
  else
39
39
  target.do_or_do_not(
40
40
  metadata.inverse_setter(target),
41
41
  base,
42
- :building => true,
42
+ :binding => true,
43
43
  :continue => false
44
44
  )
45
45
  end
@@ -65,7 +65,12 @@ module Mongoid # :nodoc:
65
65
  inverse = metadata.inverse(target)
66
66
  target.do_or_do_not(inverse).delete(base)
67
67
  else
68
- target.do_or_do_not(metadata.inverse_setter(target), nil, :continue => false)
68
+ target.do_or_do_not(
69
+ metadata.inverse_setter(target),
70
+ nil,
71
+ :binding => true,
72
+ :continue => false
73
+ )
69
74
  end
70
75
  end
71
76
  end
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The binding options.
21
21
  #
22
22
  # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -37,7 +37,7 @@ module Mongoid # :nodoc:
37
37
  # @param [ Hash ] options The binding options.
38
38
  #
39
39
  # @option options [ true, false ] :continue Continue binding the inverse.
40
- # @option options [ true, false ] :building Are we in build mode?
40
+ # @option options [ true, false ] :binding Are we in build mode?
41
41
  #
42
42
  # @since 2.0.0.rc.1
43
43
  def bind_one(doc, options = {})
@@ -47,7 +47,7 @@ module Mongoid # :nodoc:
47
47
  doc.do_or_do_not(
48
48
  name,
49
49
  base,
50
- :building => true,
50
+ :binding => true,
51
51
  :continue => false
52
52
  ) unless name == "versions="
53
53
  end
@@ -63,7 +63,7 @@ module Mongoid # :nodoc:
63
63
  # @param [ Hash ] options The binding options.
64
64
  #
65
65
  # @option options [ true, false ] :continue Continue binding the inverse.
66
- # @option options [ true, false ] :building Are we in build mode?
66
+ # @option options [ true, false ] :binding Are we in build mode?
67
67
  #
68
68
  # @since 2.0.0.rc.1
69
69
  def unbind(options = {})
@@ -78,12 +78,17 @@ module Mongoid # :nodoc:
78
78
  # @param [ Hash ] options The binding options.
79
79
  #
80
80
  # @option options [ true, false ] :continue Continue binding the inverse.
81
- # @option options [ true, false ] :building Are we in build mode?
81
+ # @option options [ true, false ] :binding Are we in build mode?
82
82
  #
83
83
  # @since 2.0.0.rc.1
84
84
  def unbind_one(doc, options = {})
85
85
  if options[:continue]
86
- doc.do_or_do_not(metadata.inverse_setter(target), nil, :continue => false)
86
+ doc.do_or_do_not(
87
+ metadata.inverse_setter(target),
88
+ nil,
89
+ :binding => true,
90
+ :continue => false
91
+ )
87
92
  end
88
93
  end
89
94
  end
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The options to pass through.
21
21
  #
22
22
  # @option options [ true, false ] :continue Do we continue binding?
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -28,7 +28,7 @@ module Mongoid # :nodoc:
28
28
  target.do_or_do_not(
29
29
  metadata.inverse_setter(target),
30
30
  base,
31
- :building => true,
31
+ :binding => true,
32
32
  :continue => false
33
33
  )
34
34
  end
@@ -45,7 +45,7 @@ module Mongoid # :nodoc:
45
45
  # @param [ Hash ] options The options to pass through.
46
46
  #
47
47
  # @option options [ true, false ] :continue Do we continue unbinding?
48
- # @option options [ true, false ] :building Are we in build mode?
48
+ # @option options [ true, false ] :binding Are we in build mode?
49
49
  #
50
50
  # @since 2.0.0.rc.1
51
51
  def unbind(options = {})
@@ -53,6 +53,7 @@ module Mongoid # :nodoc:
53
53
  target.do_or_do_not(
54
54
  metadata.inverse_setter(target),
55
55
  nil,
56
+ :binding => true,
56
57
  :continue => false
57
58
  )
58
59
  end
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The binding options.
21
21
  #
22
22
  # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -34,17 +34,13 @@ module Mongoid # :nodoc:
34
34
  if options[:continue]
35
35
  if base.referenced_many?
36
36
  target.do_or_do_not(
37
- inverse,
38
- false,
39
- :building => true,
40
- :continue => false
41
- ).push(base, :building => true, :continue => false)
37
+ inverse, false, OPTIONS
38
+ ).push(base, :binding => true, :continue => false)
42
39
  else
43
40
  target.do_or_do_not(
44
41
  metadata.inverse_setter(target),
45
42
  base,
46
- :building => true,
47
- :continue => false
43
+ OPTIONS
48
44
  )
49
45
  end
50
46
  end
@@ -67,7 +63,7 @@ module Mongoid # :nodoc:
67
63
  def unbind(options = {})
68
64
  base.do_or_do_not(metadata.foreign_key_setter, nil)
69
65
  if options[:continue]
70
- target.do_or_do_not(metadata.inverse_setter(target), nil, :continue => false)
66
+ target.do_or_do_not(metadata.inverse_setter(target), nil, OPTIONS)
71
67
  end
72
68
  end
73
69
  alias :unbind_one :unbind
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The binding options.
21
21
  #
22
22
  # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -37,7 +37,7 @@ module Mongoid # :nodoc:
37
37
  # @param [ Hash ] options The binding options.
38
38
  #
39
39
  # @option options [ true, false ] :continue Continue binding the inverse.
40
- # @option options [ true, false ] :building Are we in build mode?
40
+ # @option options [ true, false ] :binding Are we in build mode?
41
41
  #
42
42
  # @since 2.0.0.rc.1
43
43
  def bind_one(doc, options = {})
@@ -46,8 +46,7 @@ module Mongoid # :nodoc:
46
46
  doc.do_or_do_not(
47
47
  metadata.inverse_setter,
48
48
  base,
49
- :building => true,
50
- :continue => false
49
+ OPTIONS
51
50
  )
52
51
  end
53
52
  end
@@ -62,7 +61,7 @@ module Mongoid # :nodoc:
62
61
  # @param [ Hash ] options The binding options.
63
62
  #
64
63
  # @option options [ true, false ] :continue Continue binding the inverse.
65
- # @option options [ true, false ] :building Are we in build mode?
64
+ # @option options [ true, false ] :binding Are we in build mode?
66
65
  #
67
66
  # @since 2.0.0.rc.1
68
67
  def unbind(options = {})
@@ -77,13 +76,17 @@ module Mongoid # :nodoc:
77
76
  # @param [ Hash ] options The binding options.
78
77
  #
79
78
  # @option options [ true, false ] :continue Continue binding the inverse.
80
- # @option options [ true, false ] :building Are we in build mode?
79
+ # @option options [ true, false ] :binding Are we in build mode?
81
80
  #
82
81
  # @since 2.0.0.rc.1
83
82
  def unbind_one(doc, options = {})
84
83
  if options[:continue]
85
84
  doc.do_or_do_not(metadata.foreign_key_setter, nil)
86
- doc.do_or_do_not(metadata.inverse_setter, nil, :continue => false)
85
+ doc.do_or_do_not(
86
+ metadata.inverse_setter,
87
+ nil,
88
+ OPTIONS
89
+ )
87
90
  end
88
91
  end
89
92
  end
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The binding options.
21
21
  #
22
22
  # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -37,19 +37,21 @@ module Mongoid # :nodoc:
37
37
  # @param [ Hash ] options The binding options.
38
38
  #
39
39
  # @option options [ true, false ] :continue Continue binding the inverse.
40
- # @option options [ true, false ] :building Are we in build mode?
40
+ # @option options [ true, false ] :binding Are we in build mode?
41
41
  #
42
42
  # @since 2.0.0.rc.1
43
43
  def bind_one(doc, options = {})
44
44
  keys = base.do_or_do_not(metadata.foreign_key)
45
45
  keys.push(doc.id) unless keys.include?(doc.id)
46
46
  if options[:continue]
47
- doc.do_or_do_not(
48
- metadata.inverse(target),
49
- false,
50
- :building => true,
51
- :continue => false
52
- ).push(base, :continue => false)
47
+ inverse = metadata.inverse(target)
48
+ if inverse
49
+ doc.do_or_do_not(
50
+ inverse,
51
+ false,
52
+ OPTIONS
53
+ ).push(base, :continue => false)
54
+ end
53
55
  end
54
56
  end
55
57
 
@@ -63,7 +65,7 @@ module Mongoid # :nodoc:
63
65
  # @param [ Hash ] options The binding options.
64
66
  #
65
67
  # @option options [ true, false ] :continue Continue binding the inverse.
66
- # @option options [ true, false ] :building Are we in build mode?
68
+ # @option options [ true, false ] :binding Are we in build mode?
67
69
  #
68
70
  # @since 2.0.0.rc.1
69
71
  def unbind(options = {})
@@ -78,13 +80,16 @@ module Mongoid # :nodoc:
78
80
  # @param [ Hash ] options The binding options.
79
81
  #
80
82
  # @option options [ true, false ] :continue Continue binding the inverse.
81
- # @option options [ true, false ] :building Are we in build mode?
83
+ # @option options [ true, false ] :binding Are we in build mode?
82
84
  #
83
85
  # @since 2.0.0.rc.1
84
86
  def unbind_one(doc, options = {})
85
87
  base.do_or_do_not(metadata.foreign_key).delete(doc.id)
86
88
  if options[:continue]
87
- doc.do_or_do_not(metadata.inverse(target)).delete(base)
89
+ inverse = metadata.inverse(target)
90
+ if inverse
91
+ doc.do_or_do_not(inverse).delete(base)
92
+ end
88
93
  end
89
94
  end
90
95
  end
@@ -20,7 +20,7 @@ module Mongoid # :nodoc:
20
20
  # @param [ Hash ] options The options to pass through.
21
21
  #
22
22
  # @option options [ true, false ] :continue Do we continue binding?
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
26
  def bind(options = {})
@@ -29,8 +29,7 @@ module Mongoid # :nodoc:
29
29
  target.do_or_do_not(
30
30
  metadata.inverse_setter,
31
31
  base,
32
- :building => true,
33
- :continue => false
32
+ OPTIONS
34
33
  )
35
34
  end
36
35
  end
@@ -46,13 +45,17 @@ module Mongoid # :nodoc:
46
45
  # @param [ Hash ] options The options to pass through.
47
46
  #
48
47
  # @option options [ true, false ] :continue Do we continue unbinding?
49
- # @option options [ true, false ] :building Are we in build mode?
48
+ # @option options [ true, false ] :binding Are we in build mode?
50
49
  #
51
50
  # @since 2.0.0.rc.1
52
51
  def unbind(options = {})
53
52
  if options[:continue]
54
53
  target.do_or_do_not(metadata.foreign_key_setter, nil)
55
- target.do_or_do_not(metadata.inverse_setter, nil, :continue => false)
54
+ target.do_or_do_not(
55
+ metadata.inverse_setter,
56
+ nil,
57
+ OPTIONS
58
+ )
56
59
  end
57
60
  end
58
61
  alias :unbind_one :unbind
@@ -48,7 +48,7 @@ module Mongoid # :nodoc:
48
48
  def builder(name)
49
49
  tap do
50
50
  define_method("build_#{name}") do |*args|
51
- attributes = (args.any? ? args : []) + [{:building => true}]
51
+ attributes = (args.any? ? args : []) + [{:binding => true}]
52
52
  send("#{name}=", *attributes)
53
53
  end
54
54
  end
@@ -20,14 +20,14 @@ module Mongoid # :nodoc:
20
20
  #
21
21
  # @param [ Hash ] options The options to bind with.
22
22
  #
23
- # @option options [ true, false ] :building Are we in build mode?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
24
  # @option options [ true, false ] :continue Continue binding the
25
25
  # inverse?
26
26
  #
27
27
  # @since 2.0.0.rc.1
28
28
  def bind(options = {})
29
29
  binding.bind(options)
30
- base.save if target.persisted? && !options[:building]
30
+ base.save if target.persisted? && !options[:binding]
31
31
  end
32
32
 
33
33
  # Instantiate a new embedded_in relation.
@@ -58,7 +58,7 @@ module Mongoid # :nodoc:
58
58
  # @param [ Proxy ] old_target The previous target of the relation.
59
59
  # @param [ Hash ] options The options to bind with.
60
60
  #
61
- # @option options [ true, false ] :building Are we in build mode?
61
+ # @option options [ true, false ] :binding Are we in build mode?
62
62
  # @option options [ true, false ] :continue Continue binding the
63
63
  # inverse?
64
64
  #
@@ -19,14 +19,14 @@ module Mongoid # :nodoc:
19
19
  #
20
20
  # @param [ Hash ] options The options to bind with.
21
21
  #
22
- # @option options [ true, false ] :building Are we in build mode?
22
+ # @option options [ true, false ] :binding Are we in build mode?
23
23
  # @option options [ true, false ] :continue Continue binding the
24
24
  # inverse?
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def bind(options = {})
28
28
  binding.bind(options)
29
- target.each(&:save) if base.persisted? && !options[:building]
29
+ target.each(&:save) if base.persisted? && !options[:binding]
30
30
  end
31
31
 
32
32
  # Bind the inverse relation between a single document in this proxy
@@ -53,7 +53,21 @@ module Mongoid # :nodoc:
53
53
  #
54
54
  # @return [ Many ] The empty relation.
55
55
  def clear
56
- substitute(nil)
56
+ load! and substitute(nil)
57
+ end
58
+
59
+ # Returns a count of the number of documents in the association that have
60
+ # actually been persisted to the database.
61
+ #
62
+ # Use #size if you want the total number of documents.
63
+ #
64
+ # @example Get the count of persisted documents.
65
+ # person.addresses.count
66
+ #
67
+ # @return [ Integer ] The total number of persisted embedded docs, as
68
+ # flagged by the #persisted? method.
69
+ def count
70
+ target.select(&:persisted?).size
57
71
  end
58
72
 
59
73
  # Create a new document in the relation. This is essentially the same
@@ -181,6 +195,24 @@ module Mongoid # :nodoc:
181
195
  end
182
196
  end
183
197
 
198
+ # Will load the target into an array if the target had not already been
199
+ # loaded.
200
+ #
201
+ # @example Load the relation into memory.
202
+ # relation.load!
203
+ #
204
+ # @return [ Many ] The relation.
205
+ #
206
+ # @since 2.0.0.rc.5
207
+ def load!(options = {})
208
+ tap do |relation|
209
+ unless relation.loaded?
210
+ relation.bind(options)
211
+ relation.loaded = true
212
+ end
213
+ end
214
+ end
215
+
184
216
  # Paginate the association. Will create a new criteria, set the documents
185
217
  # on it and execute in an enumerable context.
186
218
  #
@@ -249,7 +281,7 @@ module Mongoid # :nodoc:
249
281
  # @param [ Array<Document> ] old_target The relations previous target.
250
282
  # @param [ Hash ] options The options to bind with.
251
283
  #
252
- # @option options [ true, false ] :building Are we in build mode?
284
+ # @option options [ true, false ] :binding Are we in build mode?
253
285
  # @option options [ true, false ] :continue Continue binding the
254
286
  # inverse?
255
287
  #
@@ -275,7 +307,7 @@ module Mongoid # :nodoc:
275
307
  #
276
308
  # @since 2.0.0.rc.1
277
309
  def append(document, options = {})
278
- target << document
310
+ load! and target.push(document)
279
311
  characterize_one(document)
280
312
  bind_one(document, options)
281
313
  document._index = target.size - 1
@@ -319,7 +351,7 @@ module Mongoid # :nodoc:
319
351
  #
320
352
  # @return [ Criteria, Object ] A Criteria or return value from the target.
321
353
  def method_missing(name, *args, &block)
322
- return super if target.respond_to?(name)
354
+ load! and return super if target.respond_to?(name)
323
355
  klass = metadata.klass
324
356
  klass.send(:with_scope, criteria) do
325
357
  klass.send(name, *args)
@@ -19,14 +19,14 @@ module Mongoid # :nodoc:
19
19
  #
20
20
  # @param [ Hash ] options The options to bind with.
21
21
  #
22
- # @option options [ true, false ] :building Are we in build mode?
22
+ # @option options [ true, false ] :binding Are we in build mode?
23
23
  # @option options [ true, false ] :continue Continue binding the
24
24
  # inverse?
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def bind(options = {})
28
28
  binding.bind(options)
29
- target.save if base.persisted? && !options[:building]
29
+ target.save if base.persisted? && !options[:binding]
30
30
  end
31
31
 
32
32
  # Instantiate a new embeds_one relation.
@@ -55,7 +55,7 @@ module Mongoid # :nodoc:
55
55
  # @param [ Document ] old_target The previous target of the relation.
56
56
  # @param [ Hash ] options The options to bind with.
57
57
  #
58
- # @option options [ true, false ] :building Are we in build mode?
58
+ # @option options [ true, false ] :binding Are we in build mode?
59
59
  # @option options [ true, false ] :continue Continue binding the
60
60
  # inverse?
61
61
  #
@@ -164,7 +164,7 @@ module Mongoid # :nodoc:
164
164
  end
165
165
  end
166
166
  alias :has_many_related :references_many
167
- alias :has_many :referenced_in
167
+ alias :has_many :references_many
168
168
 
169
169
  # Adds a relational many-to-many association between many of this
170
170
  # Document and many of another Document.
@@ -22,10 +22,8 @@ module Mongoid #:nodoc:
22
22
  def <<(*args)
23
23
  options = default_options(args)
24
24
  args.flatten.each do |doc|
25
- unless target.include?(doc)
26
- append(doc, options)
27
- doc.save if base.persisted? && !options[:building]
28
- end
25
+ append(doc, options)
26
+ doc.save if base.persisted? && !options[:binding]
29
27
  end
30
28
  end
31
29
  alias :concat :<<
@@ -43,27 +41,13 @@ module Mongoid #:nodoc:
43
41
  # @return [ Document ] The new document.
44
42
  def build(attributes = {}, type = nil)
45
43
  instantiated(type).tap do |doc|
46
- append(doc, default_options(:building => true))
44
+ append(doc, default_options(:binding => true))
47
45
  doc.write_attributes(attributes)
48
46
  doc.identify
49
47
  end
50
48
  end
51
49
  alias :new :build
52
50
 
53
- # Returns a count of the number of documents in the association that have
54
- # actually been persisted to the database.
55
- #
56
- # Use #size if you want the total number of documents.
57
- #
58
- # @example Get the count of persisted documents.
59
- # person.addresses.count
60
- #
61
- # @return [ Integer ] The total number of persisted embedded docs, as
62
- # flagged by the #persisted? method.
63
- def count
64
- target.select(&:persisted?).size
65
- end
66
-
67
51
  # Creates a new document on the references many relation. This will
68
52
  # save the document if the parent has been persisted.
69
53
  #
@@ -147,7 +131,7 @@ module Mongoid #:nodoc:
147
131
  # @return [ Hash ] The options merged with the actuals.
148
132
  def default_options(args = {})
149
133
  options = args.is_a?(Hash) ? args : args.extract_options!
150
- DEFAULT_OPTIONS.merge(options)
134
+ Mongoid.binding_defaults.merge(options)
151
135
  end
152
136
 
153
137
  # Find the first object given the supplied attributes or create/initialize it.
@@ -162,24 +146,6 @@ module Mongoid #:nodoc:
162
146
  def find_or(method, attrs = {})
163
147
  find(:first, :conditions => attrs) || send(method, attrs)
164
148
  end
165
-
166
- # If the target array does not respond to the supplied method then try to
167
- # find a named scope or criteria on the class and send the call there.
168
- #
169
- # If the method exists on the array, use the default proxy behavior.
170
- #
171
- # @param [ Symbol, String ] name The name of the method.
172
- # @param [ Array ] args The method args
173
- # @param [ Proc ] block Optional block to pass.
174
- #
175
- # @return [ Criteria, Object ] A Criteria or return value from the target.
176
- def method_missing(name, *args, &block)
177
- return super if target.respond_to?(name) || [].respond_to?(name)
178
- klass = metadata.klass
179
- klass.send(:with_scope, criteria) do
180
- klass.send(name, *args)
181
- end
182
- end
183
149
  end
184
150
  end
185
151
  end
@@ -416,11 +416,11 @@ module Mongoid # :nodoc:
416
416
  #
417
417
  # @since 2.0.0.rc.1
418
418
  def determine_foreign_key
419
- return self[:foreign_key] if self[:foreign_key]
419
+ return self[:foreign_key].to_s if self[:foreign_key]
420
420
  suffix = relation.foreign_key_suffix
421
421
  if relation.stores_foreign_key?
422
422
  if relation.macro == :references_and_referenced_in_many
423
- class_name.underscore << suffix
423
+ name.to_s.singularize << suffix
424
424
  else
425
425
  name.to_s << suffix
426
426
  end
@@ -6,6 +6,24 @@ module Mongoid # :nodoc:
6
6
  # behaviour or those proxies.
7
7
  class One < Proxy
8
8
 
9
+ # Will load the target into an array if the target had not already been
10
+ # loaded.
11
+ #
12
+ # @example Load the relation into memory.
13
+ # relation.load!
14
+ #
15
+ # @return [ One ] The relation.
16
+ #
17
+ # @since 2.0.0.rc.5
18
+ def load!(options = {})
19
+ tap do |relation|
20
+ unless relation.loaded?
21
+ relation.bind(options)
22
+ relation.loaded = true
23
+ end
24
+ end
25
+ end
26
+
9
27
  # Substitutes the supplied target documents for the existing document
10
28
  # in the relation.
11
29
  #
@@ -6,15 +6,13 @@ module Mongoid # :nodoc:
6
6
  # common behaviour for all of them.
7
7
  class Proxy
8
8
 
9
- DEFAULT_OPTIONS = { :building => false, :continue => true }
10
-
11
9
  # We undefine most methods to get them sent through to the target.
12
10
  instance_methods.each do |method|
13
11
  undef_method(method) unless
14
12
  method =~ /(^__|^send$|^object_id$|^extend$|^tap$)/
15
13
  end
16
14
 
17
- attr_accessor :base, :metadata, :target
15
+ attr_accessor :base, :loaded, :metadata, :target
18
16
 
19
17
  # Backwards compatibiloty with Mongoid beta releases.
20
18
  delegate :klass, :to => :metadata
@@ -89,7 +87,7 @@ module Mongoid # :nodoc:
89
87
  #
90
88
  # @since 2.0.0.rc.1
91
89
  def loaded?
92
- !target.is_a?(Mongoid::Criteria)
90
+ !!@loaded
93
91
  end
94
92
 
95
93
  # Takes the supplied documents and sets the metadata on them. Used when
@@ -21,7 +21,7 @@ module Mongoid # :nodoc:
21
21
  #
22
22
  # @param [ Hash ] options The options to bind with.
23
23
  #
24
- # @option options [ true, false ] :building Are we in build mode?
24
+ # @option options [ true, false ] :binding Are we in build mode?
25
25
  # @option options [ true, false ] :continue Continue binding the
26
26
  # inverse?
27
27
  #
@@ -79,7 +79,7 @@ module Mongoid # :nodoc:
79
79
  # @param [ Document, Array<Document> ] old_target The previous target.
80
80
  # @param [ Hash ] options The options to bind with.
81
81
  #
82
- # @option options [ true, false ] :building Are we in build mode?
82
+ # @option options [ true, false ] :binding Are we in build mode?
83
83
  # @option options [ true, false ] :continue Continue binding the
84
84
  # inverse?
85
85
  #
@@ -19,14 +19,14 @@ module Mongoid #:nodoc:
19
19
  #
20
20
  # @param [ Hash ] options The options to bind with.
21
21
  #
22
- # @option options [ true, false ] :building Are we in build mode?
22
+ # @option options [ true, false ] :binding Are we in build mode?
23
23
  # @option options [ true, false ] :continue Continue binding the
24
24
  # inverse?
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def bind(options = {})
28
- loaded and binding.bind(options)
29
- target.map(&:save) if base.persisted? && !options[:building]
28
+ binding.bind(options)
29
+ target.map(&:save) if base.persisted? && !options[:binding]
30
30
  end
31
31
 
32
32
  # Clear the relation. Will delete the documents from the db if they are
@@ -37,12 +37,25 @@ module Mongoid #:nodoc:
37
37
  #
38
38
  # @return [ Many ] The relation emptied.
39
39
  def clear
40
- tap do |relation|
40
+ load! and tap do |relation|
41
41
  relation.unbind(default_options)
42
42
  target.clear
43
43
  end
44
44
  end
45
45
 
46
+ # Returns a count of the number of documents in the association that have
47
+ # actually been persisted to the database.
48
+ #
49
+ # Use #size if you want the total number of documents in memory.
50
+ #
51
+ # @example Get the count of persisted documents.
52
+ # person.posts.count
53
+ #
54
+ # @return [ Integer ] The total number of persisted documents.
55
+ def count
56
+ criteria.count
57
+ end
58
+
46
59
  # Deletes all related documents from the database given the supplied
47
60
  # conditions.
48
61
  #
@@ -128,6 +141,25 @@ module Mongoid #:nodoc:
128
141
  init(base, target, metadata)
129
142
  end
130
143
 
144
+ # Will load the target into an array if the target had not already been
145
+ # loaded.
146
+ #
147
+ # @example Load the relation into memory.
148
+ # relation.load!
149
+ #
150
+ # @return [ Many ] The relation.
151
+ #
152
+ # @since 2.0.0.rc.5
153
+ def load!(options = {})
154
+ tap do |relation|
155
+ unless relation.loaded?
156
+ relation.target = target.entries
157
+ relation.bind(options)
158
+ relation.loaded = true
159
+ end
160
+ end
161
+ end
162
+
131
163
  # Removes all associations between the base document and the target
132
164
  # documents by deleting the foreign keys and the references, orphaning
133
165
  # the target documents in the process.
@@ -137,7 +169,7 @@ module Mongoid #:nodoc:
137
169
  #
138
170
  # @since 2.0.0.rc.1
139
171
  def nullify
140
- loaded and target.each do |doc|
172
+ load! and target.each do |doc|
141
173
  doc.send(metadata.foreign_key_setter, nil)
142
174
  doc.send(
143
175
  :remove_instance_variable, "@#{metadata.inverse(doc)}"
@@ -157,7 +189,7 @@ module Mongoid #:nodoc:
157
189
  # @param [ Array<Document> ] target The replacement target.
158
190
  # @param [ Hash ] options The options to bind with.
159
191
  #
160
- # @option options [ true, false ] :building Are we in build mode?
192
+ # @option options [ true, false ] :binding Are we in build mode?
161
193
  # @option options [ true, false ] :continue Continue binding the
162
194
  # inverse?
163
195
  #
@@ -178,7 +210,7 @@ module Mongoid #:nodoc:
178
210
  #
179
211
  # @param [ Hash ] options The options to bind with.
180
212
  #
181
- # @option options [ true, false ] :building Are we in build mode?
213
+ # @option options [ true, false ] :binding Are we in build mode?
182
214
  # @option options [ true, false ] :continue Continue binding the
183
215
  # inverse?
184
216
  #
@@ -201,7 +233,7 @@ module Mongoid #:nodoc:
201
233
  #
202
234
  # @since 2.0.0.rc.1
203
235
  def append(document, options = {})
204
- loaded and target.push(document)
236
+ load! and target.push(document)
205
237
  characterize_one(document)
206
238
  binding.bind_one(document, options)
207
239
  end
@@ -228,21 +260,24 @@ module Mongoid #:nodoc:
228
260
  #
229
261
  # @return [ Criteria ] A new criteria.
230
262
  def criteria
231
- metadata.klass.criteria(false)
263
+ metadata.klass.where(metadata.foreign_key => base.id)
232
264
  end
233
265
 
234
- # Will load the target into an array if the target had not already been
235
- # loaded.
266
+ # If the target array does not respond to the supplied method then try to
267
+ # find a named scope or criteria on the class and send the call there.
236
268
  #
237
- # @example Load the relation into memory.
238
- # relation.loaded
269
+ # If the method exists on the array, use the default proxy behavior.
239
270
  #
240
- # @return [ Many ] The relation.
271
+ # @param [ Symbol, String ] name The name of the method.
272
+ # @param [ Array ] args The method args
273
+ # @param [ Proc ] block Optional block to pass.
241
274
  #
242
- # @since 2.0.0.rc.1
243
- def loaded
244
- tap do |relation|
245
- relation.target = target.entries unless loaded?
275
+ # @return [ Criteria, Object ] A Criteria or return value from the target.
276
+ def method_missing(name, *args, &block)
277
+ load! and return super if [].respond_to?(name)
278
+ klass = metadata.klass
279
+ klass.send(:with_scope, criteria) do
280
+ klass.send(name, *args)
246
281
  end
247
282
  end
248
283
 
@@ -5,43 +5,7 @@ module Mongoid # :nodoc:
5
5
 
6
6
  # This class defines the behaviour for all relations that are a
7
7
  # many-to-many between documents in different collections.
8
- class ManyToMany < Relations::Many
9
-
10
- # Binds the base object to the inverse of the relation. This is so we
11
- # are referenced to the actual objects themselves and dont hit the
12
- # database twice when setting the relations up.
13
- #
14
- # This is called after first creating the relation, or if a new object
15
- # is set on the relation.
16
- #
17
- # @example Bind the relation.
18
- # person.preferences.bind
19
- #
20
- # @param [ Hash ] options The options to bind with.
21
- #
22
- # @option options [ true, false ] :building Are we in build mode?
23
- # @option options [ true, false ] :continue Continue binding the
24
- # inverse?
25
- #
26
- # @since 2.0.0.rc.1
27
- def bind(options = {})
28
- loaded and binding.bind(options)
29
- target.map(&:save) if base.persisted? && !options[:building]
30
- end
31
-
32
- # Clear the relation. Will delete the documents from the db if they are
33
- # already persisted.
34
- #
35
- # @example Clear the relation.
36
- # person.preferences.clear
37
- #
38
- # @return [ Many ] The relation emptied.
39
- def clear
40
- tap do |relation|
41
- relation.unbind(default_options)
42
- target.clear
43
- end
44
- end
8
+ class ManyToMany < Referenced::Many
45
9
 
46
10
  # Delete a single document from the relation.
47
11
  #
@@ -52,8 +16,9 @@ module Mongoid # :nodoc:
52
16
  #
53
17
  # @since 2.0.0.rc.1
54
18
  def delete(document, options = {})
55
- target.delete(document)
56
- binding.unbind_one(document, options)
19
+ target.delete(document).tap do |doc|
20
+ binding.unbind_one(doc, default_options.merge!(options)) if doc
21
+ end
57
22
  end
58
23
 
59
24
  # Deletes all related documents from the database given the supplied
@@ -126,19 +91,6 @@ module Mongoid # :nodoc:
126
91
  klass.find(arg, :conditions => selector)
127
92
  end
128
93
 
129
- # Instantiate a new references_many relation. Will set the foreign key
130
- # and the base on the inverse object.
131
- #
132
- # @example Create the new relation.
133
- # Referenced::ManyToMany.new(base, target, metadata)
134
- #
135
- # @param [ Document ] base The document this relation hangs off of.
136
- # @param [ Array<Document> ] target The target of the relation.
137
- # @param [ Metadata ] metadata The relation's metadata.
138
- def initialize(base, target, metadata)
139
- init(base, target, metadata)
140
- end
141
-
142
94
  # Removes all associations between the base document and the target
143
95
  # documents by deleting the foreign keys and the references, orphaning
144
96
  # the target documents in the process.
@@ -148,7 +100,7 @@ module Mongoid # :nodoc:
148
100
  #
149
101
  # @since 2.0.0.rc.1
150
102
  def nullify
151
- loaded and target.each do |doc|
103
+ load! and target.each do |doc|
152
104
  base.send(metadata.foreign_key).delete(doc.id)
153
105
  dereference(doc)
154
106
  end
@@ -166,7 +118,7 @@ module Mongoid # :nodoc:
166
118
  # @param [ Array<Document> ] target The replacement target.
167
119
  # @param [ Hash ] options The options to bind with.
168
120
  #
169
- # @option options [ true, false ] :building Are we in build mode?
121
+ # @option options [ true, false ] :binding Are we in build mode?
170
122
  # @option options [ true, false ] :continue Continue binding the
171
123
  # inverse?
172
124
  #
@@ -195,7 +147,7 @@ module Mongoid # :nodoc:
195
147
  #
196
148
  # @param [ Hash ] options The options to bind with.
197
149
  #
198
- # @option options [ true, false ] :building Are we in build mode?
150
+ # @option options [ true, false ] :binding Are we in build mode?
199
151
  # @option options [ true, false ] :continue Continue binding the
200
152
  # inverse?
201
153
  #
@@ -208,21 +160,6 @@ module Mongoid # :nodoc:
208
160
 
209
161
  private
210
162
 
211
- # Appends the document to the target array, updating the index on the
212
- # document at the same time.
213
- #
214
- # @example Append the document to the relation.
215
- # relation.append(document)
216
- #
217
- # @param [ Document ] document The document to append to the target.
218
- #
219
- # @since 2.0.0.rc.1
220
- def append(document, options = {})
221
- loaded and target.push(document)
222
- characterize_one(document)
223
- binding.bind_one(document, options)
224
- end
225
-
226
163
  # Instantiate the binding associated with this relation.
227
164
  #
228
165
  # @example Get the binding.
@@ -245,7 +182,7 @@ module Mongoid # :nodoc:
245
182
  #
246
183
  # @return [ Criteria ] A new criteria.
247
184
  def criteria
248
- metadata.klass.criteria(false)
185
+ metadata.klass.any_in(metadata.inverse_foreign_key => [ base.id ])
249
186
  end
250
187
 
251
188
  # Dereferences the supplied document from the base of the relation.
@@ -260,21 +197,6 @@ module Mongoid # :nodoc:
260
197
  document.save
261
198
  end
262
199
 
263
- # Will load the target into an array if the target had not already been
264
- # loaded.
265
- #
266
- # @example Load the relation into memory.
267
- # relation.loaded
268
- #
269
- # @return [ ManyToMany ] The relation.
270
- #
271
- # @since 2.0.0.rc.1
272
- def loaded
273
- tap do |relation|
274
- relation.target = target.entries if target.is_a?(Mongoid::Criteria)
275
- end
276
- end
277
-
278
200
  class << self
279
201
 
280
202
  # Return the builder that is responsible for generating the documents
@@ -19,14 +19,14 @@ module Mongoid # :nodoc:
19
19
  #
20
20
  # @param [ Hash ] options The options to bind with.
21
21
  #
22
- # @option options [ true, false ] :building Are we in build mode?
22
+ # @option options [ true, false ] :binding Are we in build mode?
23
23
  # @option options [ true, false ] :continue Continue binding the
24
24
  # inverse?
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def bind(options = {})
28
28
  binding.bind(options)
29
- target.save if base.persisted? && !options[:building]
29
+ target.save if base.persisted? && !options[:binding]
30
30
  end
31
31
 
32
32
  # Instantiate a new references_one relation. Will set the foreign key
@@ -70,7 +70,7 @@ module Mongoid # :nodoc:
70
70
  # @param [ Document ] old_target The previous target of the relation.
71
71
  # @param [ Hash ] options The options to bind with.
72
72
  #
73
- # @option options [ true, false ] :building Are we in build mode?
73
+ # @option options [ true, false ] :binding Are we in build mode?
74
74
  # @option options [ true, false ] :continue Continue binding the
75
75
  # inverse?
76
76
  #
@@ -30,7 +30,11 @@ module Mongoid #:nodoc:
30
30
  #
31
31
  # @since 2.0.0.rc.1
32
32
  def read_attribute_for_validation(attr)
33
- relations[attr.to_s] ? send(attr, false, :continue => false) : send(attr)
33
+ if relations[attr.to_s]
34
+ send(attr, false, :continue => false, :eager => true)
35
+ else
36
+ send(attr)
37
+ end
34
38
  end
35
39
 
36
40
  # Used to prevent infinite loops in associated validations.
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc
3
- VERSION = "2.0.0.rc.4"
3
+ VERSION = "2.0.0.rc.5"
4
4
  end
metadata CHANGED
@@ -7,8 +7,8 @@ version: !ruby/object:Gem::Version
7
7
  - 0
8
8
  - 0
9
9
  - rc
10
- - 4
11
- version: 2.0.0.rc.4
10
+ - 5
11
+ version: 2.0.0.rc.5
12
12
  platform: ruby
13
13
  authors:
14
14
  - Durran Jordan
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-01-13 00:00:00 +01:00
19
+ date: 2011-01-16 00:00:00 +01:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -172,6 +172,7 @@ files:
172
172
  - lib/mongoid/collections.rb
173
173
  - lib/mongoid/components.rb
174
174
  - lib/mongoid/config/database.rb
175
+ - lib/mongoid/config/replset_database.rb
175
176
  - lib/mongoid/config.rb
176
177
  - lib/mongoid/contexts/enumerable/sort.rb
177
178
  - lib/mongoid/contexts/enumerable.rb
@@ -354,7 +355,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
354
355
  requirements:
355
356
  - - ">="
356
357
  - !ruby/object:Gem::Version
357
- hash: 588977190582466333
358
+ hash: -3904513981579822953
358
359
  segments:
359
360
  - 0
360
361
  version: "0"