Yii Framework Forum

[Extension] Mongoyii


(Sam Millman) #1

This is the place to discuss the MongoYii extension: http://www.yiiframework.com/extension/mongoyii/

You can also file a GitHub issue as usual: https://github.com/Sammaye/MongoYii/issues


(Schanz15) #2

Thanks for the discussion topic.

Whoops - I did not associate the comment with the "@example" - Mainly because this annotation is new to me, and there is a line break between the annotation and the example itself.

Thats cool - but these functions are spread all over the classes. Adding the access scope modifiers would be nice :).

I got two more things to add to my list that i wrote in the comment section earlier:

Named Scopes

Are these supposed to work? I cannot use the standard approach to define a named scape.

e.g.


public function type($myType)

{

    $crit = new EMongoCriteria(array('condition' => array('attr' => $myType)));

    $this->getDbCriteria()->mergeWith($crit); <-- FAILS. $this->getDbCriteria() is an array, not an object!


    return $this;

}

Also if I try it the other way around - $crit->mergeWith($this->getDbCriteria()) - it is not working because the dbCriteria is possibly just NULL.

EMongoDocument::getPrimaryKey()

I know that the primary key - at this stage - is not supposed to change. But if you could add a method to return the value of the primary key (just like CActiveRecord::primaryKey) i could use this in my code to ensure that i get the correct value.

I don’t know if this makes sense because at this stage of the extension it would return just the “_id” property as hardcoded value. Since I am not that much into MongoDB I also don’t know if it is common to change the name of the PK to something else.


(Sam Millman) #3

How do you mean?

In models using this extension this function should only exist in one place, in the EMongoDocument.

I wish I had taken out the criteria class now.

It doesn’t work with the merging in scopes, they are completely array based.

If I am honest I only added the EMongoCriteria class in case there was something I was missing about it.

Hmm yea I have changed the way to define scopes, I should add that to the documentation with an example. Basically I have taken out the criteria object from it entirely.

Aye I can do that: https://github.com/Sammaye/MongoYii/commit/cec1cd6a3707cdd1968c8d9dc11900631e033d7b


(Sam Millman) #4

I have added a note about custom scopes now: http://www.yiiframework.com/extension/mongoyii/#hh18

If you want to use the code shown there you will need to update your checked out version, I added an extra function to aid in merging criteria easily.


(Schanz15) #5

I mean that many functions within your extension lacks of the (private/protected/public) access scope modifier

EMongoModel::__construct()

EMongoModel::attributeNames()

EMongoClient::init()

EMongoClient::connect()

Almost the whole EMongoCursor class

to name a few.

Thanks a lot for your insane fast responses and implementations. Named scopes helps me a lot :). Too bad that the aggregation framework is not supported somehow. But I understand that it isn’t fitting well into AR :(.


(Sam Millman) #6

Hmm I could always add a aggregation helper to the model so that you don’t have to use the mongodb object directly, that should at least make the collection names more modular within the app and also hopefully that should be all accessors plugged in now :)

Thanks for the awesome testing you have been doing, it has really helped :D


(Schanz15) #7

If a shortcut like MyCollection::model()->aggregate() instead of Yii::app()->mongodb->MyCollection->aggregate() makes sense, I would be glad to have this implemented. Otherwise I am totaly fine with the extension at this point :).


(Sam Millman) #8

Indeed so you can just call the model and not have to type in the collection name directly like, as you said:


User::model()->aggregate(array(

    array('$group'=>array('_id'=>'$username','sum'=>array('$sum'=>1)))

));

It is there as well:

Was in the last commit :)

Awesome! Thanks again for testing


(Schanz15) #9

Just tested the named scopes and I found a Bug there.

Lets say I’ve Collection::model()->scope()->find(); the scope applies some conditions to the criteria.

Now if I call Collection::model()->getDbCriteria() I expect to have a totaly new model and therefore an empty criteria. But to my suprise the criteria from the scope is still present in the criteria of the new model!

BTW: Could you add an alias for findBy_id and name it findByPk - So it can be used the Yii way ;).


(Sam Millman) #10

Indeed I did notice that about scopes. Originally I thought it was a bug but I apply scopes like Yii does so I eventually just said that maybe it is a Yii thing (those parts are actually a straight copy from CActiveRecord). I will take a new look into that now that I kow it ain’t.

Added the Alias :)


(Sam Millman) #11

Ok I think I found the bug.

I checked CActiveRecored again and it turns out that when Yii queries and it calls "applyScopes" it also resets them in that function so that the cached static instance of the model is never effected by finds() etc.

Should be fixed now.


(Schanz15) #12

Amazing how fast you are - Seems to be working :)


(Schanz15) #13

Using EMongoDataProvider with CListView reveals an other small bug. Yii expects the data returned from CDataProvider::fetchData() to be index based. Currently its an associative array where the key is representing the PK of the document.

The fix is very simple: In EMongoDataProvider:108 change this line


return iterator_to_array($this->_cursor);

to


return iterator_to_array($this->_cursor, false);

in order to generate an index-based array.


(Sam Millman) #14

Indeed I do believe that function should return a index-based array, commited :)


#15

Surely there must be a way to put both a composer compatible autoloader in the source tree, so that this can be put on packagist? I’m not sure I see how there would be a conflict with that one and the regular Yii autoloader, the latter which would simply be loading classes as usual and the composer one wouldn’t be used in this case. Thoughts?


(Sam Millman) #16

I must admit I haven’t ever used composer, I only briefly looked into it. I am looking into composer support for this extension now.


#17

Great, thanks :) I think it’s super easy, just have a look at https://github.com/Crisu83/yii-less or some other one of Crisu’s extensions to see an example.

I’ve recently started using Composer and it’s a real breeze to just add a line in your ‘require’ array and run composer update and have it all managed for you. Also easy to set up namespaces and autoloading.


(Sam Millman) #18

Indeed that is very simple, I don’t even need to use the composer autoloader if I just have to provide configuration like that.

I’ll look into completing this today.

I have written a composer.json file now which should work but whenever I attempt to upload it to the packagist site it keeps saying they had a problem their end, I try to clean my browser session and re-log in but then I get a 500 error :\.

So it will be up as soon as that gets fixed


(Sam Millman) #19

Ha typical, as soon as I say that it works: https://packagist.org/packages/sammaye/mongoyii


(St Agrail) #20

Thanks for great extension, Sammaye.

Is there an easy way to display validation errors of embedded documents and embedded arrays through CHtml::errorSummary($model) or CHtml::error($model)? How do you realize validation process in your applications?