[cbmongodb] How to populate and save models?

I have this model:

`

component name=“Report” extends=“cbmongodb.models.ActiveEntity” collection=“report” accessors=true{

/Schema Properties/
property name=“host” schema=true validate=“url”;
property name=“user_id” schema=true validate=“string”;

}

`

The model has onsly 2 properties. Now when I try to save I pass this model a lot more of data and then I try to save:

`

function save(){

rc.report.host = “google.it”;
rc.report.ip = “123.32.213”;
rc.report.user_id = “1”;
rc.report.date = Now();
rc.report.somedata = {
data1=12,
data2=3455
};

var myreport = getModel(‘Report@api’).populate(rc.report);

myreport.create();
dump(report);abort;

}

`

However only the properties declared in my model are saved, the pthers are skipped.

I should declare all properties that I want to save in my model?

I need to declare a property “report” that will contain all nested document data?

`

property name=“report” schema=true validate=“string”;

`

ORM doesn’t work that way.

Tropicalista,

The point of CBMongoDB’s ActiveEntity is to enforce the schema defined in the properties. Schema enforcement is by design. Because the default document is mapped by the properties, only the schema defined in that default document persists to the database.

In other words, you need to map properties if you want them to persist via ActiveEntity.

If you need to store additional data in your collections you’re going to have to go directly to the MongoCollection methods:

Report.getCollectionObject().save(rc.report)

Since the document is scoped, as is, on entity load, you’ll still be able to see those items, but it’s going to cause problems if you try to use ActiveEntity saves or updates on the reports at a later date.

The way I typically handle variable data is to place it in named property struct. I can put anything in that struct, as long as it’s defined, and it will persist.

property name="reportContent" schema=true validate="struct";

Then I can populate that struct with whatever content I need to:

Report.setReportContent(rc.report)

Many thanks Jon for clarify this.

I have another question: if I load an object from my DB and populate it

`

var myreport = getModel(‘Report@api’).reset().where(‘host’,‘google.it’).find();
myreport.populate(rc.report);

`

how can I save it?

`
myreport.update();

`

This does not persist data in the DB.

Right. That’s where the ActiveEntity enforcement is going to kick in and and re-set the document schema to the default. You also can’t use populate() to set unmapped elements.

You’re going to have to go back to the Collection object to persist that data and then reload the entity:

var myreport = getModel('Report@api').reset().where('host','google.it').find();

var reportDoc = myreport.getDocument();

structMerge( report, rc.report, true );

myreport.getCollectionObject().replaceOne( { "_id": reportDoc[ "_id" ] }, reportDoc );

myreport.reload();

There are a number of update methods, depending on what you want to do. In the example above, I just used the replaceOne method to completely replace the doc. You can browse through the APIDocs for models.Mongo.Collection to see what each does: Generated Documentation (CBMongoDB v3.2.1.1)

That said, if you can do it, creating a mapped container property for your variable data, as mentioned before, will make your life much easier.

Jon

BTW, I should have used structAppend instead of structMerge there… Oops… :slight_smile:

I ended up using reportContent property as suggested.

Thanks