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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"