Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

HasMany duplicate entires #13

Closed
dominis opened this Issue · 3 comments

3 participants

@dominis

The hasMany relations never detects if the given object exists it just saves every object.
So if you run the following code from the examples:

<?php
$aBook = new Book();
$aBook->title = 'new title';
$aBook->pageNumber = 1500;
$aBook->publishedDate = strtotime('2009-09-11');
$author1 = new Author();
$author1->name = 'Moose';
$author2 = new Author();
$author2->name = 'test2';
$aBook->authors[] = $author1;
$aBook->authors[] = $author2;
$aBook->save();

$bBook = new Book();
$bBook->title = 'new title';
$bBook->pageNumber = 1500;
$bBook->publishedDate = strtotime('2009-09-11');
$author1 = new Author();
$author1->name = 'shark';
$author2 = new Author();
$author2->name = 'test2';
$bBook->authors[] = $author1;
$bBook->authors[] = $author2;
$bBook->save();

It creates two test2 author. I think it's not the expected result.

@mgrandi

the way mongodb works is that every document has its own Object id, so even though you are adding two 'author' objects with the same name, they are still different documents in the database with unique object ID's. You should probably check to see if there are any authors with the same name before you add it to the database

@dominis

ok i get it, but let's look it from another angle. I've just added a unique index to the author documents' name field. It now could not create new author documents, but does not saves the proper IDs into the book docs.

@a-musing-moose

Hey Dominis,

This is expected behaviour - MongoDB and by extension Morph has no idea the first $author2 and the second $author2 are the same author. Behind the scenes Morph uses DB refs for has type relationships. To properly generate the DBRef Morph needs to know a couple of things:

1) The collection containing the related object
2) The _id of the related object.

Basically this is what mgrandi was saying above. (@mgrandi - thanks for replying by the way).

Morph obtains both of these things from a saved instance of the related objects. Therefore you would need to retrieve the author from the DB to obtain the related object. Or alternatively you could adjust your example above to use:

<?php
$aBook = new Book();
$aBook->title = 'new title';
$aBook->pageNumber = 1500;
$aBook->publishedDate = strtotime('2009-09-11');
$author1 = new Author();
$author1->name = 'Moose';
$author2 = new Author();
$author2->name = 'test2';
$aBook->authors[] = $author1;
$aBook->authors[] = $author2;
$aBook->save();

$bBook = new Book();
$bBook->title = 'new title';
$bBook->pageNumber = 1500;
$bBook->publishedDate = strtotime('2009-09-11');
$author1 = new Author();
$author1->name = 'shark';
//$author2 = new Author();
//$author2->name = 'test2';
$bBook->authors[] = $author1;
$bBook->authors[] = $author2;
$bBook->save();

i.e. just use the $author2 reference defined previously - once the parent $aBook object is saved, so is $author2. Therefore is has an _id field and can be used successfully in $bBook.

Alternatively in a more real work example you probably would (as @mgrandi suggests) search for the author first to ensure he/she doesn't already exists.

So something like:

<?php
$bBook = new Book();
$bBook->title = 'new title';
$bBook->pageNumber = 1500;
$bBook->publishedDate = strtotime('2009-09-11');

$authorNames = array('shark', 'test2');

foreach ($authorNames as $authorName) {
   $q = \morph\Query::instance()->property('name')->equals($authorName);
   try {
      //try to find the specified author by name
      $author = \morph\Storage::instance()->findOneByQuery(new Author, $q);
   } catch (\morph\exception\ObjectNotFound $e) {
      //can't find an existing one - so we create a new one.
      $author = new Author();
      $author->name = $authorName;
   }
   $bBook->authors[] = $author;
}

$bBook->save();

So not too much extra work.

I hope that makes sense.

Regards,
Jon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.