@@ -140,6 +140,8 @@ public function get()
140140 */
141141 public function save (Model $ model )
142142 {
143+ $ this ->updateTimestamps ($ model );
144+
143145 // Insert a new document.
144146 if ( ! $ model ->exists )
145147 {
@@ -154,34 +156,40 @@ public function save(Model $model)
154156 }
155157
156158 /**
157- * Perform a model insert operation .
159+ * Attach a model instance to the parent model without persistence .
158160 *
159161 * @param \Illuminate\Database\Eloquent\Model $model
160162 * @return \Illuminate\Database\Eloquent\Model
161163 */
162- protected function performInsert (Model $ model )
164+ public function associate (Model $ model )
163165 {
164- // Create a new key.
165- if ( ! $ model ->getAttribute ( ' _id ' ) )
166+ // Insert the related model in the parent instance
167+ if ( ! $ model ->exists )
166168 {
167- $ model -> setAttribute ( ' _id ' , new MongoId );
169+ return $ this -> associateNew ( $ model );
168170 }
169171
170- // Update timestamps.
171- $ this ->updateTimestamps ($ model );
172-
173- // Push the document to the database.
174- $ result = $ this ->query ->push ($ this ->localKey , $ model ->getAttributes (), true );
175-
176- $ documents = $ this ->getEmbeddedRecords ();
172+ // Update the related model in the parent instance
173+ else
174+ {
175+ return $ this ->associateExisting ($ model );
176+ }
177177
178- // Add the document to the parent model.
179- $ documents [] = $ model ->getAttributes ();
178+ }
180179
181- $ this ->setEmbeddedRecords ($ documents );
180+ /**
181+ * Perform a model insert operation.
182+ *
183+ * @param \Illuminate\Database\Eloquent\Model $model
184+ * @return \Illuminate\Database\Eloquent\Model
185+ */
186+ protected function performInsert (Model $ model )
187+ {
188+ // Insert the related model in the parent instance
189+ $ this ->associateNew ($ model );
182190
183- // Mark the model as existing .
184- $ model ->exists = true ;
191+ // Push the document to the database .
192+ $ result = $ this -> query -> push ( $ this -> localKey , $ model ->getAttributes (), true ) ;
185193
186194 return $ result ? $ model : false ;
187195 }
@@ -194,8 +202,8 @@ protected function performInsert(Model $model)
194202 */
195203 protected function performUpdate (Model $ model )
196204 {
197- // Update timestamps.
198- $ this ->updateTimestamps ($ model );
205+ // Update the related model in the parent instance
206+ $ this ->associateExisting ($ model );
199207
200208 // Get the correct foreign key value.
201209 $ id = $ this ->getForeignKeyValue ($ model ->getKey ());
@@ -204,6 +212,44 @@ protected function performUpdate(Model $model)
204212 $ result = $ this ->query ->where ($ this ->localKey . '. ' . $ model ->getKeyName (), $ id )
205213 ->update (array ($ this ->localKey . '.$ ' => $ model ->getAttributes ()));
206214
215+ return $ result ? $ model : false ;
216+ }
217+
218+ /**
219+ * Attach a new model without persistence
220+ *
221+ * @param \Illuminate\Database\Eloquent\Model $model
222+ * @return \Illuminate\Database\Eloquent\Model
223+ */
224+ protected function associateNew ($ model )
225+ {
226+ // Create a new key.
227+ if ( ! $ model ->getAttribute ('_id ' ))
228+ {
229+ $ model ->setAttribute ('_id ' , new MongoId );
230+ }
231+
232+ $ documents = $ this ->getEmbeddedRecords ();
233+
234+ // Add the document to the parent model.
235+ $ documents [] = $ model ->getAttributes ();
236+
237+ $ this ->setEmbeddedRecords ($ documents );
238+
239+ // Mark the model as existing.
240+ $ model ->exists = true ;
241+
242+ return $ model ;
243+ }
244+
245+ /**
246+ * Update an existing model without persistence
247+ *
248+ * @param \Illuminate\Database\Eloquent\Model $model
249+ * @return \Illuminate\Database\Eloquent\Model
250+ */
251+ protected function associateExisting ($ model )
252+ {
207253 // Get existing embedded documents.
208254 $ documents = $ this ->getEmbeddedRecords ();
209255
@@ -212,18 +258,18 @@ protected function performUpdate(Model $model)
212258 $ key = $ model ->getKey ();
213259
214260 // Replace the document in the parent model.
215- foreach ($ documents as $ i => $ document )
261+ foreach ($ documents as & $ document )
216262 {
217263 if ($ document [$ primaryKey ] == $ key )
218264 {
219- $ documents [ $ i ] = $ model ->getAttributes ();
265+ $ document = $ model ->getAttributes ();
220266 break ;
221267 }
222268 }
223269
224270 $ this ->setEmbeddedRecords ($ documents );
225271
226- return $ result ? $ model : false ;
272+ return $ model ;
227273 }
228274
229275 /**
@@ -273,32 +319,36 @@ public function createMany(array $records)
273319 /**
274320 * Destroy the embedded models for the given IDs.
275321 *
276- * @param array|int $ids
322+ * @param mixed $ids
277323 * @return int
278324 */
279325 public function destroy ($ ids = array ())
280326 {
281- // We'll initialize a count here so we will return the total number of deletes
282- // for the operation. The developers can then check this number as a boolean
283- // type value or get this total count of records deleted for logging, etc.
284- $ count = 0 ;
285-
286- if ($ ids instanceof Model) $ ids = (array ) $ ids ->getKey ();
287-
288- // If associated IDs were passed to the method we will only delete those
289- // associations, otherwise all of the association ties will be broken.
290- // We'll return the numbers of affected rows when we do the deletes.
291- $ ids = (array ) $ ids ;
327+ $ ids = $ this ->getIdsArrayFrom ($ ids );
292328
293329 $ primaryKey = $ this ->related ->getKeyName ();
294330
295331 // Pull the documents from the database.
296332 foreach ($ ids as $ id )
297333 {
298334 $ this ->query ->pull ($ this ->localKey , array ($ primaryKey => $ this ->getForeignKeyValue ($ id )));
299- $ count ++;
300335 }
301336
337+ return $ this ->dissociate ($ ids );
338+ }
339+
340+ /**
341+ * Dissociate the embedded models for the given IDs without persistence.
342+ *
343+ * @param mixed $ids
344+ * @return int
345+ */
346+ public function dissociate ($ ids = array ())
347+ {
348+ $ ids = $ this ->getIdsArrayFrom ($ ids );
349+
350+ $ primaryKey = $ this ->related ->getKeyName ();
351+
302352 // Get existing embedded documents.
303353 $ documents = $ this ->getEmbeddedRecords ();
304354
@@ -313,7 +363,28 @@ public function destroy($ids = array())
313363
314364 $ this ->setEmbeddedRecords ($ documents );
315365
316- return $ count ;
366+ // We return the total number of deletes for the operation. The developers
367+ // can then check this number as a boolean type value or get this total count
368+ // of records deleted for logging, etc.
369+ return count ($ ids );
370+ }
371+
372+ /**
373+ * Transform single ID, single Model or array of Models into an array of IDs
374+ *
375+ * @param mixed $ids
376+ * @return int
377+ */
378+ protected function getIdsArrayFrom ($ ids )
379+ {
380+ if (! is_array ($ ids )) $ ids = array ($ ids );
381+
382+ foreach ($ ids as &$ id )
383+ {
384+ if ($ id instanceof Model) $ id = $ id ->getKey ();
385+ }
386+
387+ return $ ids ;
317388 }
318389
319390 /**
0 commit comments