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

Issue deleting an referenced domain object from an array field #11

Open
michaeldewildt opened this issue Jun 12, 2013 · 1 comment
Open

Comments

@michaeldewildt
Copy link

Righto lets say I have a BlogPost DomainObject that contains an ArrayField of Comments as follows.

class Comment extends Moa\DomainObject
{

}

class Post extends Moa\DomainObject
{
    public function properties()
    {
        return array(
            'comments' => new Moa\Types\ArrayField(array(
                'type' => new Moa\Types\ReferenceField(array(
                    'type' => 'Comment'
                )),
            )),
        );
    }
}

There is an issue where if I delete a comment from within that referenced field the post does not know it is gone until the LazyProperty is consumed in some way. For example:

Comment::remove(array('_id' => new \MongoId('someCommentId')));

$post = Post::findOne(array('_id' => new \MongoId('somePostId')));

echo count($post->comments); //prints 1 which is incorrect

echo isset($post->comments[0]); //prints 1 which is incorrect

echo $post->comments[0]; //prints nothing which is correct because it's deleted

foreach ($category->comments as $comment) {
    echo $comment; //Wait what... how did you get here?            
}

The problem is the instance is not loaded until the array is referenced. It returns an array of lazy properties instead of an expected empty set that can cause some crazy bugs with iterators. Especially in twig!

I am not sure how to fix this issue without breaking lazy loading for everything else!

@lwc @alecsloman I'd be keen to hear your thoughts.

@rexmortus
Copy link

Yeah, I see the issue. It would be cool if a domain object is referenced somewhere, when you deleted the object, the reference field is also deleted, but this does not appear to be the case.

This line:

Comment::remove(array('_id' => new \MongoId('someCommentId'))); will delete the comment domain object from the Comment collection.

Now, having deleted the comment object, you inspect the post's comment array, and rightfully, it says there's an object in there, which there is: it's still got the reference field, it's just that when you go to hydrate it, you don't get anything because the domain object is gone.

The problem is... mongo doesn't make it particularly easy for an object to have an index of where's it's been referenced. Unfortunately, it seems like the only reasonable way to handle this, is in your command where you delete the the comment, you should also unset the reference field on the post object. It sucks to couple them so tightly, but at least then your iterators won't be hoodwinked.

I'll have a think about this going forward, because it's definitely a problem.

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

No branches or pull requests

2 participants