Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for discriminatorField/discriminatorMap for ReferenceOne. #626

Closed
wants to merge 1 commit into from
Closed

Adds support for discriminatorField/discriminatorMap for ReferenceOne. #626

wants to merge 1 commit into from

Conversation

Parad0X
Copy link
Contributor

@Parad0X Parad0X commented Jul 2, 2013

So ReferenceOne with discriminator map/type doesn't seem to be working. It's not saving the type. This is what my mapping file looks like:

referenceOne:
    model:
        discriminatorField: model_type
        discriminatorMap:
            user: Blah\Bundle\UserBundle\Model\User
            reservation: Blah\Bundle\WebBundle\Model\Reservation

And all I have in the DB is:

{ ... "model" : DBRef("reservations", ObjectId("51cf0b65d0c3f5661000001a")) ... }

model_type is not set.

This pull request fixes this issue by saving the type.

Before I spend any more time on this could someone take a quick look and tell me if I'm going in the right direction.

@Parad0X
Copy link
Contributor Author

Parad0X commented Jul 2, 2013

@jmikola could you take a look when you get a chance?

@jmikola
Copy link
Member

jmikola commented Jul 3, 2013

I read #625 yesterday, and just got back to ODM after wrapping up the doctrine/mongodb PR. I'm going to create a failing test for this, and then I'll look into the patch.

@jmikola
Copy link
Member

jmikola commented Jul 3, 2013

@Parad0X: I can't reproduce this in the following test case. The discriminatorField option doesn't seem to apply in this case -- that's for setting on a parent class if you were doing single-collection inheritance. For references (one or many), Doctrine is just going to embed a _doctrine_class_name property in the DBRef object, which will contain the short name from the map.

Without a map defined, ODM will store the entire class name in that property. You can quickly test that by removing the discriminatorMap option from the annotation on GH625Document.

namespace Doctrine\ODM\MongoDB\Tests\Functional\Ticket;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

class GH625Test extends \Doctrine\ODM\MongoDB\Tests\BaseTest
{
    public function testReferenceOneSupportsDiscriminatorMap()
    {
        $documentClass = __NAMESPACE__ . '\GH625Document';

        $foo = new GH625Foo();
        $bar = new GH625Bar();

        $document1 = new GH625Document();
        $document1->ref = $foo;

        $document2 = new GH625Document();
        $document2->ref = $bar;

        $this->dm->persist($document1);
        $this->dm->persist($document2);
        $this->dm->flush();
        $this->dm->clear();

        $document1 = $this->dm->find($documentClass, $document1->id);
        $this->assertInstanceOf('Doctrine\ODM\MongoDB\Proxy\Proxy', $document1->ref);
        $this->assertInstanceOf(__NAMESPACE__ . '\GH625Foo', $document1->ref);

        $document2 = $this->dm->find($documentClass, $document2->id);
        $this->assertInstanceOf('Doctrine\ODM\MongoDB\Proxy\Proxy', $document2->ref);
        $this->assertInstanceOf(__NAMESPACE__ . '\GH625Bar', $document2->ref);
    }
}

/** @ODM\Document */
class GH625Document
{
    /** @ODM\Id */
    public $id;

    /** @ODM\ReferenceOne(discriminatorMap={"foo":"GH625Foo","bar":"GH625Bar"}, cascade="persist") */
    public $ref;
}

/** @ODM\Document */
class GH625Foo
{
    /** @ODM\Id */
    public $id;
}

/** @ODM\Document */
class GH625Bar
{
    /** @ODM\Id */
    public $id;
}

@Parad0X
Copy link
Contributor Author

Parad0X commented Jul 3, 2013

Ah I see. Apparently I got confused because when I was looking in mongo I saw:

{ "model" : DBRef("reservations", ObjectId("51d2f501d0c3f5df10000000")) }

but in reality its:

{ 'model' => { '$ref' => 'reservations', '$id' => MongoId('51d2f501d0c3f5df10000000'), '$db' => 'test', 'model_type' => 'reservation' } }

Mongo shell replaces any object containing $db, $ref and $id with DBRef so that's why I wasn't seeing model_type. Ok. This is closed :) Thanks 👍

@Parad0X Parad0X closed this Jul 3, 2013
@Parad0X Parad0X deleted the polymorphic-reference-one branch July 3, 2013 17:05
@jmikola
Copy link
Member

jmikola commented Jul 3, 2013

Yup. That aspect of the shell bit me hard once: https://speakerdeck.com/jmikola/using-mongodb-responsibly?slide=32

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants