mongomodel 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +23 -11
  3. data/gemfiles/rails-3.2.gemfile +2 -2
  4. data/gemfiles/rails-4-observers.gemfile +1 -1
  5. data/gemfiles/rails-4.1.gemfile +2 -2
  6. data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
  7. data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
  8. data/gemfiles/rails-5.1.gemfile +10 -0
  9. data/gemfiles/rails-5.2.gemfile +10 -0
  10. data/lib/mongomodel.rb +15 -15
  11. data/lib/mongomodel/attributes/mongo.rb +7 -7
  12. data/lib/mongomodel/attributes/store.rb +4 -4
  13. data/lib/mongomodel/attributes/typecasting.rb +7 -7
  14. data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
  15. data/lib/mongomodel/compatibility/mongoid.rb +3 -3
  16. data/lib/mongomodel/concerns/abstract_class.rb +3 -3
  17. data/lib/mongomodel/concerns/activemodel.rb +4 -4
  18. data/lib/mongomodel/concerns/associations.rb +8 -8
  19. data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
  20. data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
  21. data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
  22. data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
  23. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
  24. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
  25. data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
  26. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
  27. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
  28. data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
  29. data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
  30. data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
  31. data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
  32. data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
  33. data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
  34. data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
  35. data/lib/mongomodel/concerns/attributes.rb +18 -18
  36. data/lib/mongomodel/concerns/callbacks.rb +7 -7
  37. data/lib/mongomodel/concerns/document_parent.rb +2 -2
  38. data/lib/mongomodel/concerns/logging.rb +2 -2
  39. data/lib/mongomodel/concerns/map_reduce.rb +11 -11
  40. data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
  41. data/lib/mongomodel/concerns/properties.rb +18 -18
  42. data/lib/mongomodel/concerns/record_status.rb +9 -13
  43. data/lib/mongomodel/concerns/serialization.rb +4 -4
  44. data/lib/mongomodel/concerns/timestamps.rb +4 -4
  45. data/lib/mongomodel/concerns/translation.rb +2 -2
  46. data/lib/mongomodel/concerns/validations.rb +5 -5
  47. data/lib/mongomodel/concerns/validations/associated.rb +1 -1
  48. data/lib/mongomodel/document.rb +6 -6
  49. data/lib/mongomodel/document/callbacks.rb +15 -21
  50. data/lib/mongomodel/document/collection_modifiers.rb +5 -5
  51. data/lib/mongomodel/document/dynamic_finders.rb +1 -1
  52. data/lib/mongomodel/document/indexes.rb +19 -19
  53. data/lib/mongomodel/document/optimistic_locking.rb +7 -7
  54. data/lib/mongomodel/document/persistence.rb +23 -23
  55. data/lib/mongomodel/document/scopes.rb +20 -20
  56. data/lib/mongomodel/document/validations.rb +6 -6
  57. data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
  58. data/lib/mongomodel/embedded_document.rb +11 -11
  59. data/lib/mongomodel/locale/en.yml +0 -1
  60. data/lib/mongomodel/log_subscriber.rb +5 -5
  61. data/lib/mongomodel/railtie.rb +13 -13
  62. data/lib/mongomodel/support/collection.rb +31 -31
  63. data/lib/mongomodel/support/configuration.rb +11 -11
  64. data/lib/mongomodel/support/core_extensions.rb +1 -1
  65. data/lib/mongomodel/support/dynamic_finder.rb +12 -12
  66. data/lib/mongomodel/support/exceptions.rb +6 -6
  67. data/lib/mongomodel/support/instrumented_collection.rb +20 -20
  68. data/lib/mongomodel/support/map.rb +33 -33
  69. data/lib/mongomodel/support/mongo_operator.rb +6 -6
  70. data/lib/mongomodel/support/mongo_options.rb +18 -18
  71. data/lib/mongomodel/support/mongo_order.rb +16 -16
  72. data/lib/mongomodel/support/paginator.rb +8 -8
  73. data/lib/mongomodel/support/reference.rb +10 -10
  74. data/lib/mongomodel/support/scope.rb +37 -37
  75. data/lib/mongomodel/support/scope/array_methods.rb +1 -1
  76. data/lib/mongomodel/support/scope/batches.rb +1 -1
  77. data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
  78. data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
  79. data/lib/mongomodel/support/scope/load_methods.rb +1 -1
  80. data/lib/mongomodel/support/scope/pagination.rb +1 -1
  81. data/lib/mongomodel/support/scope/query_methods.rb +6 -6
  82. data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
  83. data/lib/mongomodel/support/types.rb +2 -2
  84. data/lib/mongomodel/support/types/array.rb +1 -1
  85. data/lib/mongomodel/support/types/boolean.rb +3 -3
  86. data/lib/mongomodel/support/types/custom.rb +3 -3
  87. data/lib/mongomodel/support/types/date.rb +2 -2
  88. data/lib/mongomodel/support/types/date_time.rb +6 -16
  89. data/lib/mongomodel/support/types/float.rb +1 -1
  90. data/lib/mongomodel/support/types/hash.rb +1 -1
  91. data/lib/mongomodel/support/types/integer.rb +13 -10
  92. data/lib/mongomodel/support/types/object.rb +5 -5
  93. data/lib/mongomodel/support/types/rational.rb +3 -3
  94. data/lib/mongomodel/support/types/time.rb +2 -2
  95. data/lib/mongomodel/version.rb +1 -1
  96. data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
  97. data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
  98. data/mongomodel.gemspec +5 -4
  99. data/spec/mongomodel/attributes/store_spec.rb +21 -21
  100. data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
  101. data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
  102. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
  103. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
  104. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
  105. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
  106. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
  107. data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
  108. data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
  109. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
  110. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
  111. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
  112. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
  113. data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
  114. data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
  115. data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
  116. data/spec/mongomodel/concerns/logging_spec.rb +5 -3
  117. data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
  118. data/spec/mongomodel/concerns/observing_spec.rb +3 -3
  119. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
  120. data/spec/mongomodel/concerns/properties_spec.rb +11 -11
  121. data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
  122. data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
  123. data/spec/mongomodel/concerns/validations_spec.rb +41 -38
  124. data/spec/mongomodel/document/callbacks_spec.rb +20 -16
  125. data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
  126. data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
  127. data/spec/mongomodel/document/finders_spec.rb +15 -15
  128. data/spec/mongomodel/document/indexes_spec.rb +29 -29
  129. data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
  130. data/spec/mongomodel/document/persistence_spec.rb +39 -39
  131. data/spec/mongomodel/document/scopes_spec.rb +17 -17
  132. data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
  133. data/spec/mongomodel/document/validations_spec.rb +35 -35
  134. data/spec/mongomodel/document_spec.rb +19 -19
  135. data/spec/mongomodel/embedded_document_spec.rb +19 -19
  136. data/spec/mongomodel/mongomodel_spec.rb +7 -6
  137. data/spec/mongomodel/support/collection_spec.rb +54 -54
  138. data/spec/mongomodel/support/configuration_spec.rb +1 -1
  139. data/spec/mongomodel/support/map_spec.rb +66 -66
  140. data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
  141. data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
  142. data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
  143. data/spec/mongomodel/support/paginator_spec.rb +15 -15
  144. data/spec/mongomodel/support/property_spec.rb +29 -23
  145. data/spec/mongomodel/support/scope_spec.rb +205 -204
  146. data/spec/spec_helper.rb +13 -2
  147. data/spec/support/callbacks.rb +3 -8
  148. data/spec/support/helpers/define_class.rb +7 -7
  149. data/spec/support/helpers/document_finder_stubs.rb +6 -6
  150. data/spec/support/helpers/specs_for.rb +1 -1
  151. data/spec/support/helpers/validations.rb +1 -1
  152. data/spec/support/matchers/find_with.rb +8 -8
  153. data/spec/support/matchers/respond_to_boolean.rb +3 -3
  154. data/spec/support/matchers/run_callbacks.rb +6 -9
  155. data/spec/support/models.rb +5 -5
  156. metadata +23 -7
@@ -6,26 +6,26 @@ module MongoModel
6
6
  class Association
7
7
  attr_reader :definition, :instance
8
8
  delegate :name, :klass, :polymorphic?, :to => :definition
9
-
9
+
10
10
  def initialize(definition, instance)
11
11
  @definition, @instance = definition, instance
12
12
  end
13
-
13
+
14
14
  def proxy
15
15
  @proxy ||= proxy_class.new(self)
16
16
  end
17
-
17
+
18
18
  def replace(obj)
19
19
  proxy.target = obj
20
20
  proxy
21
21
  end
22
-
22
+
23
23
  def ensure_class(value)
24
24
  unless value.is_a?(klass) || value.class.name.constantize <= klass.name.constantize
25
25
  raise AssociationTypeMismatch, "#{klass} expected, got #{value.class}"
26
26
  end
27
27
  end
28
-
28
+
29
29
  protected
30
30
  def proxy_class
31
31
  self.class.parent::Proxy rescue Base::Proxy
@@ -29,7 +29,7 @@ module MongoModel
29
29
  name.to_s.classify.constantize
30
30
  end
31
31
  end
32
-
32
+
33
33
  def singular_name
34
34
  name.to_s.singularize
35
35
  end
@@ -37,15 +37,15 @@ module MongoModel
37
37
  def polymorphic?
38
38
  options[:polymorphic]
39
39
  end
40
-
40
+
41
41
  def collection?
42
42
  true
43
43
  end
44
-
44
+
45
45
  def scope
46
46
  klass.scoped.apply_finder_options(scope_options)
47
47
  end
48
-
48
+
49
49
  def scope_options
50
50
  options.slice(:conditions, :select, :offset, :limit, :order)
51
51
  end
@@ -12,7 +12,7 @@ module MongoModel
12
12
  def initialize(association)
13
13
  @association = association
14
14
  end
15
-
15
+
16
16
  def target=(new_target)
17
17
  @target = new_target
18
18
  loaded!
@@ -2,52 +2,52 @@ module MongoModel
2
2
  module Associations
3
3
  class BelongsTo < Base::Definition
4
4
  def foreign_key
5
- @foreign_key ||= :"#{name}_id"
5
+ @foreign_key ||= options[:foreign_key] || :"#{name}_id"
6
6
  end
7
-
7
+
8
8
  def type_key
9
- @type_key ||= :"#{name}_type"
9
+ @type_key ||= options[:type_key] || :"#{name}_type"
10
10
  end
11
-
11
+
12
12
  def collection?
13
13
  false
14
14
  end
15
-
15
+
16
16
  properties do |association|
17
17
  property association.foreign_key, MongoModel::Reference, :internal => true
18
18
  property association.type_key, String, :internal => true if association.polymorphic?
19
19
  end
20
-
20
+
21
21
  methods do |association|
22
22
  define_method(association.name) do |*args|
23
23
  force_reload = args.first unless args.empty?
24
-
24
+
25
25
  proxy = associations[association.name].proxy
26
-
26
+
27
27
  proxy.reset if force_reload
28
28
  proxy.target.nil? ? nil : proxy
29
29
  end
30
-
30
+
31
31
  define_method("#{association.name}=") { |obj| associations[association.name].replace(obj) }
32
-
32
+
33
33
  unless association.polymorphic?
34
34
  define_method("build_#{association.name}") do |*args|
35
35
  associations[association.name].replace(association.klass.new(*args))
36
36
  end
37
-
37
+
38
38
  define_method("create_#{association.name}") do |*args|
39
39
  associations[association.name].replace(association.klass.create(*args))
40
40
  end
41
41
  end
42
42
  end
43
-
43
+
44
44
  class Association < Base::Association
45
45
  delegate :foreign_key, :type_key, :to => :definition
46
-
46
+
47
47
  def target_id
48
48
  instance[foreign_key]
49
49
  end
50
-
50
+
51
51
  def target_class
52
52
  if polymorphic?
53
53
  instance[type_key].constantize rescue nil
@@ -55,20 +55,20 @@ module MongoModel
55
55
  klass
56
56
  end
57
57
  end
58
-
58
+
59
59
  def replace(obj)
60
60
  ensure_class(obj) if obj && !polymorphic?
61
-
61
+
62
62
  instance[foreign_key] = obj ? obj.id : nil
63
63
  instance[type_key] = obj ? obj.class : nil if polymorphic?
64
-
64
+
65
65
  super
66
66
  end
67
-
67
+
68
68
  def find_target
69
69
  target_class.find(target_id) if target_id && target_class
70
70
  end
71
-
71
+
72
72
  protected
73
73
  def proxy_class
74
74
  Base::Proxy
@@ -4,23 +4,23 @@ module MongoModel
4
4
  def foreign_key
5
5
  @foreign_key ||= options[:foreign_key] || :"#{inverse_of}_id"
6
6
  end
7
-
7
+
8
8
  def inverse_of
9
9
  @inverse_of ||= options[:inverse_of] || owner.to_s.demodulize.underscore.singularize.to_sym
10
10
  end
11
-
11
+
12
12
  def define!
13
13
  raise "has_many :by => :foreign_key is only valid on Document" unless owner.ancestors.include?(Document)
14
-
14
+
15
15
  super
16
-
16
+
17
17
  define_dependency_callbacks!
18
18
  self
19
19
  end
20
-
20
+
21
21
  def define_dependency_callbacks!
22
22
  association = self
23
-
23
+
24
24
  if options[:dependent] == :destroy
25
25
  owner.before_destroy do
26
26
  send(association.name).each { |child| child.destroy }
@@ -31,75 +31,75 @@ module MongoModel
31
31
  end
32
32
  end
33
33
  end
34
-
34
+
35
35
  methods do |association|
36
36
  define_method(association.name) { associations[association.name].proxy }
37
37
  define_method("#{association.name}=") { |obj| associations[association.name].replace(obj) }
38
38
  end
39
-
39
+
40
40
  class Association < Base::Association
41
41
  delegate :foreign_key, :inverse_of, :to => :definition
42
-
42
+
43
43
  def find_target
44
44
  scoped.each { |doc|
45
45
  doc.send("#{inverse_of}=", instance) if doc.respond_to?("#{inverse_of}=")
46
46
  } + new_documents
47
47
  end
48
-
48
+
49
49
  def build(*args, &block)
50
50
  doc = scoped.new(*args, &block)
51
51
  new_documents << doc
52
52
  doc
53
53
  end
54
-
54
+
55
55
  def create(*args)
56
56
  scoped.create(*args) do |doc|
57
57
  set_inverse_association(doc)
58
58
  yield doc if block_given?
59
59
  end
60
60
  end
61
-
61
+
62
62
  def create!(*args)
63
63
  scoped.create!(*args) do |doc|
64
64
  set_inverse_association(doc)
65
65
  yield doc if block_given?
66
66
  end
67
67
  end
68
-
68
+
69
69
  def replace(array)
70
70
  ensure_class(array)
71
71
  array.each { |doc| assign(doc) }
72
72
  super
73
73
  end
74
-
74
+
75
75
  def assign(doc)
76
76
  set_inverse_association(doc)
77
77
  doc.save(false) unless doc.new_record?
78
78
  end
79
-
79
+
80
80
  def unset(doc)
81
81
  if doc.respond_to?("#{inverse_of}=")
82
82
  doc.send("#{inverse_of}=", nil) if doc.send(inverse_of) == instance
83
83
  else
84
84
  doc[foreign_key] = nil if doc[foreign_key] == instance.id
85
85
  end
86
-
86
+
87
87
  doc.save(false) unless doc.new_record?
88
88
  end
89
-
89
+
90
90
  def scoped
91
91
  definition.scope.where(foreign_key => instance.id).on_load { |doc| set_inverse_association(doc) }
92
92
  end
93
-
93
+
94
94
  def ensure_class(array)
95
95
  array.is_a?(Array) ? array.each { |i| super(i) } : super
96
96
  end
97
-
97
+
98
98
  protected
99
99
  def new_documents
100
100
  @new_documents ||= []
101
101
  end
102
-
102
+
103
103
  def set_inverse_association(doc)
104
104
  if doc.respond_to?("#{inverse_of}=")
105
105
  doc.send("#{inverse_of}=", instance)
@@ -107,39 +107,39 @@ module MongoModel
107
107
  doc[foreign_key] = instance.id
108
108
  end
109
109
  end
110
-
110
+
111
111
  def proxy_class
112
112
  Proxy
113
113
  end
114
114
  end
115
-
115
+
116
116
  class Proxy < Base::Proxy
117
117
  # Pass these methods to the scope rather than the Array target
118
118
  OVERRIDE_METHODS = [ :find, :first, :last, :count, :paginate ]
119
-
119
+
120
120
  delegate :ensure_class, :to => :association
121
-
121
+
122
122
  def build(*args)
123
123
  association.build(*args) do |doc|
124
124
  self << doc
125
125
  yield doc if block_given?
126
126
  end
127
127
  end
128
-
128
+
129
129
  def create(*args)
130
130
  association.create(*args) do |doc|
131
131
  self << doc
132
132
  yield doc if block_given?
133
133
  end
134
134
  end
135
-
135
+
136
136
  def create!(*args)
137
137
  association.create!(*args) do |doc|
138
138
  self << doc
139
139
  yield doc if block_given?
140
140
  end
141
141
  end
142
-
142
+
143
143
  def []=(index, doc)
144
144
  ensure_class(doc)
145
145
  association.unset(target[index]) if target[index]
@@ -147,7 +147,7 @@ module MongoModel
147
147
  super if loaded?
148
148
  self
149
149
  end
150
-
150
+
151
151
  def <<(*documents)
152
152
  documents.flatten!
153
153
  ensure_class(documents)
@@ -155,40 +155,40 @@ module MongoModel
155
155
  super if loaded?
156
156
  self
157
157
  end
158
-
158
+
159
159
  alias_method :push, :<<
160
160
  alias_method :concat, :<<
161
-
161
+
162
162
  def insert(index, doc)
163
163
  ensure_class(doc)
164
164
  association.assign(doc)
165
165
  super if loaded?
166
166
  self
167
167
  end
168
-
168
+
169
169
  def unshift(*documents)
170
170
  ensure_class(documents)
171
171
  documents.each { |doc| association.assign(doc) }
172
172
  super if loaded?
173
173
  self
174
174
  end
175
-
175
+
176
176
  def delete(doc)
177
177
  association.unset(doc)
178
178
  super
179
179
  self
180
180
  end
181
-
181
+
182
182
  def delete_at(index)
183
183
  association.unset(target[index])
184
184
  super
185
185
  self
186
186
  end
187
-
187
+
188
188
  def ids
189
189
  target.map { |doc| doc.id }
190
190
  end
191
-
191
+
192
192
  def select(*args, &block)
193
193
  if args.empty?
194
194
  target.select(&block)
@@ -196,7 +196,7 @@ module MongoModel
196
196
  association.scoped.send(:select, *args)
197
197
  end
198
198
  end
199
-
199
+
200
200
  private
201
201
  def method_missing(method, *args, &block)
202
202
  if Array.method_defined?(method) && !OVERRIDE_METHODS.include?(method)
@@ -4,16 +4,16 @@ module MongoModel
4
4
  def property_name
5
5
  @property_name ||= :"#{singular_name}_ids"
6
6
  end
7
-
7
+
8
8
  def define!
9
9
  super
10
10
  define_dependency_callbacks!
11
11
  self
12
12
  end
13
-
13
+
14
14
  def define_dependency_callbacks!
15
15
  association = self
16
-
16
+
17
17
  if options[:dependent] == :destroy
18
18
  owner.before_destroy do
19
19
  send(association.name).each { |child| child.destroy }
@@ -24,30 +24,30 @@ module MongoModel
24
24
  end
25
25
  end
26
26
  end
27
-
27
+
28
28
  properties do |association|
29
29
  property association.property_name, Collection[MongoModel::Reference], :internal => true, :default => []
30
30
  end
31
-
31
+
32
32
  methods do |association|
33
33
  define_method(association.name) { associations[association.name].proxy }
34
34
  define_method("#{association.name}=") { |obj| associations[association.name].replace(obj) }
35
35
  end
36
-
36
+
37
37
  class Association < Base::Association
38
38
  delegate :property_name, :to => :definition
39
-
39
+
40
40
  def ids
41
41
  instance[property_name]
42
42
  end
43
-
43
+
44
44
  def replace(array)
45
45
  ensure_class(array)
46
-
46
+
47
47
  instance[property_name] = array.map { |i| i.id }
48
48
  super
49
49
  end
50
-
50
+
51
51
  def find_target
52
52
  if ids.any?
53
53
  docs = Array.wrap(definition.scope.where(:id.in => (ids - new_document_ids))) + new_documents
@@ -56,134 +56,134 @@ module MongoModel
56
56
  []
57
57
  end
58
58
  end
59
-
59
+
60
60
  def build(*args, &block)
61
61
  doc = scoped.new(*args, &block)
62
62
  new_documents << doc
63
63
  doc
64
64
  end
65
-
65
+
66
66
  def create(*args, &block)
67
67
  scoped.create(*args, &block)
68
68
  end
69
-
69
+
70
70
  def scoped
71
71
  definition.scope.where(:id.in => ids)
72
72
  end
73
-
73
+
74
74
  def ensure_class(array)
75
75
  array.is_a?(Array) ? array.each { |i| super(i) } : super
76
76
  end
77
-
77
+
78
78
  protected
79
79
  def new_documents
80
80
  @new_documents ||= []
81
81
  end
82
-
82
+
83
83
  def new_document_ids
84
84
  new_documents.map { |doc| doc.id }
85
85
  end
86
-
86
+
87
87
  def proxy_class
88
88
  Proxy
89
89
  end
90
90
  end
91
-
91
+
92
92
  class Proxy < Base::Proxy
93
93
  # Pass these methods to the association class rather than the Array target
94
94
  OVERRIDE_METHODS = [ :find ]
95
-
95
+
96
96
  delegate :ensure_class, :to => :association
97
-
97
+
98
98
  def build(*args, &block)
99
99
  doc = association.build(*args, &block)
100
100
  self << doc
101
101
  doc
102
102
  end
103
-
103
+
104
104
  def create(*args, &block)
105
105
  doc = association.create(*args, &block)
106
106
  self << doc
107
107
  doc
108
108
  end
109
-
109
+
110
110
  def []=(index, doc)
111
111
  ensure_class(doc)
112
112
  super if loaded?
113
113
  ids[index] = doc.id
114
114
  self
115
115
  end
116
-
116
+
117
117
  def <<(doc)
118
118
  ensure_class(doc)
119
119
  super if loaded?
120
120
  ids << doc.id
121
121
  self
122
122
  end
123
-
123
+
124
124
  def concat(documents)
125
125
  ensure_class(documents)
126
126
  super if loaded?
127
127
  ids.concat(documents.map { |doc| doc.id })
128
128
  self
129
129
  end
130
-
130
+
131
131
  def insert(index, doc)
132
132
  ensure_class(doc)
133
133
  super if loaded?
134
134
  ids.insert(index, doc.id)
135
135
  self
136
136
  end
137
-
137
+
138
138
  def replace(documents)
139
139
  ensure_class(documents)
140
140
  super if loaded?
141
141
  ids.replace(documents.map { |doc| doc.id })
142
142
  self
143
143
  end
144
-
144
+
145
145
  def push(*documents)
146
146
  ensure_class(documents)
147
147
  super if loaded?
148
148
  ids.push(*documents.map { |doc| doc.id })
149
149
  self
150
150
  end
151
-
151
+
152
152
  def unshift(*documents)
153
153
  ensure_class(documents)
154
154
  super if loaded?
155
155
  ids.unshift(*documents.map { |doc| doc.id })
156
156
  self
157
157
  end
158
-
158
+
159
159
  def clear
160
160
  super if loaded?
161
161
  ids.clear
162
162
  self
163
163
  end
164
-
164
+
165
165
  def delete(doc)
166
166
  super if loaded?
167
167
  ids.delete(doc.id)
168
168
  self
169
169
  end
170
-
170
+
171
171
  def delete_at(index)
172
172
  super if loaded?
173
173
  ids.delete_at(index)
174
174
  self
175
175
  end
176
-
176
+
177
177
  def delete_if(&block)
178
178
  super
179
179
  ids.replace(map { |doc| doc.id })
180
180
  self
181
181
  end
182
-
182
+
183
183
  def ids
184
184
  association.ids
185
185
  end
186
-
186
+
187
187
  private
188
188
  def method_missing(method_id, *args, &block)
189
189
  if target.respond_to?(method_id) && !OVERRIDE_METHODS.include?(method_id.to_sym)