coen-hyde / Shanty-Mongo

Shanty Mongo is a mongodb library for the Zend Framework. Its intention is to make working with mongodb documents as natural and as simple as possible. In particular allowing embedded documents to also have custom document classes.
Other
200 stars 52 forks source link

Simple question #74

Closed zelf closed 12 years ago

zelf commented 12 years ago

I'm completely new to Mongodb (and obviously to Shanty_mongo)

It seams to be easy, i can do pretty much what I want exept this:

I'm taking your exemple:

class Name extends Shanty_Mongo_Document
{
    protected static $_requirements = array(
        'first' => 'Required',
        'last' => 'Required',
    );

}

class User extends Shanty_Mongo_Document 
{
    protected static $_db = 'forum';
    protected static $_collection = 'user';

    protected static $_requirements = array(
        'name' => array('Document:Name', 'Required')
    );
}

Is this supposed to store the two documents in mongoDb? (name and user)

$user = new User();
$user->name->first = 'Bob';
$user->name->last = 'Jane';
$user->save();

Because it's not working. It stores the user. but there is no document in my "name"collection.

I also tried

$name = new Name();
$name->first = 'Bob';
$name->last = 'Jane';

$user = new User();
$user->name = $name;
$user->save();

Which create the user object but not the name.

This works:

$name = new Name();
$name->first = 'Bob';
$name->last = 'Jane';
$name->save();
$user = new User();
$user->name = $name;
$user->save();

But not what i'm looking for. It must be something about the requirement I did not understand because it seams that my application does not care about it.

Any help is welcome thank you very much.

coen-hyde commented 12 years ago

Hi Zelf,

The power of mongodb is embeded documents. ie documents inside documents. Unless you specify 'AsReference', sub documents will be embeded.

In you user collection you will see documents that look like this.

{ "name":{ "first":"Bob", "last":"Jane" } }

I hope that helps.

Cheers, Coen

On Fri, Mar 30, 2012 at 9:31 AM, zelf reply@reply.github.com wrote:

I'm completely new to Mongodb (and obviously to Shanty_mongo)

It seams to be easy, i can do pretty much what I want exept this:

I'm taking your exemple:

class Name extends Shanty_Mongo_Document
{
   protected static $_requirements = array(
       'first' => 'Required',
       'last' => 'Required',
   );

}

class User extends Shanty_Mongo_Document
{
   protected static $_db = 'forum';
   protected static $_collection = 'user';

   protected static $_requirements = array(
       'name' => array('Document:Name', 'Required')
   );
}

Is this supposed to store the two documents in mongoDb? (name and user)

$user = new User();
$user->name->first = 'Bob';
$user->name->last = 'Jane';
$user->save();

Because it's not working. It stores the user. but there is no document in my "name"collection.

I also tried

$name = new Name();
$name->first = 'Bob';
$name->last = 'Jane';

$user = new User();
$user->name = $name;
$user->save();

Which create the user object but not the name.

This works:

$name = new Name();
$name->first = 'Bob';
$name->last = 'Jane';
$name->save();
$user = new User();
$user->name = $name;
$user->save();

But not what i'm looking for. It must be something about the requirement I did not understand because it seams that my application does not care about it.

Any help is welcome thank you very much.


Reply to this email directly or view it on GitHub: https://github.com/coen-hyde/Shanty-Mongo/issues/74

zelf commented 12 years ago

Wow thank you for your quick answer.

That is exactly what I was looking for.

If I understand it right: I can store the first document and specify it AsReference instead of required in the second document.

I'll will try that. Thank you very much and good night (morning for you I guess)

coen-hyde commented 12 years ago

You can still specify 'Required' if the field is required, but if you add 'AsReference' then it will be stored in it's own collection.

On Fri, Mar 30, 2012 at 10:31 AM, zelf reply@reply.github.com wrote:

Wow thank you for your quick answer.

That is exactly what I was looking for.

If I understand it right: I can store the first document and specify it AsReference instead of required in the second document.

I'll will try that. Thank you very much and good night (morning for you I guess)


Reply to this email directly or view it on GitHub: https://github.com/coen-hyde/Shanty-Mongo/issues/74#issuecomment-4834318

zelf commented 12 years ago

Hi,

Thanks for the tips but:

Message: Can not create reference. Document is not a root document.

I'm lost...! If you have any explanation...

Thank you anyway.

class Application_Model_Planets extends Shanty_Mongo_Document 
{
    protected static $_db = 'mydb';
    protected static $_collection = 'planets';
    protected static $_requirements = array( 
              'name' => array('Document:Application_Model_Lang', 'Required', 'AsReference'));
}
class Application_Model_Lang extends Shanty_Mongo_Document 
{
    protected static $_db = 'mydb';
    protected static $_collection = 'lang';
    protected static $_requirements = array(    
        'en' =>  'Required',
        'fr' =>  'Required',
        'es' =>  'Required'
    );
}
    public function indexAction() {
        $planet = new Application_Model_Planets();
        $planet->name->en = "en";
        $planet->name->fr ="fr" ;
        $planet->name->es = "es";
        $planet->save();
  }
coen-hyde commented 12 years ago

Remove 'AsReference' from the 'name' requirements in the planets model that way the lang document will be embedded. It appears the best way to model your data would be to have the lang document as an embedded document not in a separate collection as you are trying to do.

If you want to store documents as references you have to create them outside the scope of the model they are going to have the reference saved into.

ie. $lang = new Application_Model_Lang(); $lang->en = "en"; $lang->fr = "fr"; $lang->es = "es"; $planet->name = $lang

But as i said in this case i think that wouldn't be the best approach.

zelf commented 12 years ago

Ok that is perfect.

I need the reference because I have translators working on the site too.

Thank you very much. You've done an amazing work (now that i understand how it work aha..)

zelf commented 12 years ago

Hi, me again. i'd like to do this:

$planet= Application_Model_Planets::all(array('name.en' => 'earth'));

Name is a reference. And for now i just get a blank page.

Is this possible? Or is it the reason why you told my code wont be the best approach?

Thank you again.

coen-hyde commented 12 years ago

Hi Zelf,

Unfortunately you can't search references like that and yeah that's one of the reasons why i suggested you should embed the document.

Cheers, Coen