vadimdemedes / mongorito

🍹 MongoDB ODM for Node.js apps based on Redux
1.38k stars 90 forks source link

Automatically adding object properties to models? #178

Closed jrista closed 7 years ago

jrista commented 7 years ago

I am really liking Mongorito so far, after having first installed it a couple of days ago. There was only one thing I did not really like about it, the necessity of using get/set to retrieve and modify data. I decided to create an extension of the Model class, called AutoModel (probably a better name for it) that automatically expands all the data properties from the document passed to the constructor into object properties that internally call get and set:

var Model = Mongorito.Model;

class AutoModel extends Model {
    constructor(doc) {
        super(doc);
        if (doc) {
            // Describe data properties based on data
            let props = {};
            for (let key of Object.keys(doc)) {
                props[key] = {
                    configurable: true,
                    enumerable: true,
                    get: () => super.get(key),
                    set: val => super.set(key, val)
                };
            }

            // Attach data properties
            Object.defineProperties(this, props);

            // Assign values to data properties
            for (let key of Object.keys(doc)) {
                this[key] = doc[key];
            }
        }
    }
}

module.exports = AutoModel;

This allows us to have richer models with first-class data properties, and eliminates the necessity of directly calling get or set, without losing the Redux functionality. Is there any chance this could be included in the framework? I would be happy to submit a PR.

vadimdemedes commented 7 years ago

Glad you're liking Mongorito!

I don't think I want this to be in the core, but feel free to build and release a plugin for it! There's a section in readme about extending Mongorito at the end. Let me know if you have any questions!

niallobrien commented 7 years ago

@jrista Care to release it on npm as a plugin?

jrista commented 7 years ago

I'll see what I can do. It's really handy having it be automatic, so if I can find some time this weekend I'll try to get something uploaded to github and published to NPM. I gotta learn how to write plugins for Mongorito though. ;)

niallobrien commented 7 years ago

Awesome! 🤘

vadimdemedes commented 7 years ago

@jrista let us know if you run into any problems while writing plugins ;)

vadimdemedes commented 7 years ago

@niallobrien Thanks for taking care of this issue!

jrista commented 6 years ago

Hey guys. I just thought I'd check back in. Making this whole thing work ended up being more complex than originally thought. The first approach did not handle new ad-hoc properties added to objects properly. Trying to do it as a plugin ended up getting a lot more complex than I had hoped.

I ultimately ended up returning a new JS Proxy object from the constructor of my AutoModel class that intercepted set, which was the simplest way of ensuring new properties were defined that properly called the .get and .set methods of the underlying model. It all seems to work now, however it isn't done as a plugin.