0

I'm kind of new in node.js and sails but it's easy so I like it :) I'm working actually with the sails Framework 0.10rc3 with MongoDB ans sails-mongo.

I know that the contributors of waterline are not big fan of embedded documents in models as for mongodb (https://github.com/balderdashy/sails-mongo/issues/44#issuecomment-35561040) but anyway, I wanted to know how the 'this' variable works in them and how to retrieve the current element in the inner-array.

Here is an exemple of model (that we can call ProjetSpan):

module.exports = {

attributes: {

        proj: 
        {
            model:'Projet'
        },

        spans:
        {
            start:
            {
                type: 'DATETIME',
                required: true,
                datetime: true,
                before: function() {
                    if (this.end < this.proj.end)
                        return this.end;
                    else
                        return this.proj.end;
                }
            },

            end:
            {
                type: 'DATETIME',
                required: true,
                datetime: true,
                after: function() {
                    if (this.start > this.proj.start)
                        return this.start;
                    else
                        return this.proj.start;
                }
            }
        }
}

};

how the 'this' will work in this case ? is 'this' a span (and so this.end will work and not this.proj.end) or is 'this' a ProjetSpan (ans so this.proj.end works but not this.end) ?

Finally, how to make this.end (the variable in the current span) and this.proj.end (the variable in the association of the current document) work in this embedded context ?

DestyNova
  • 726
  • 8
  • 21

1 Answers1

1

Waterline doesn't support embedded documents at all, except for supplying the json data type. So, your model example won't work in Sails, and would need to be rewritten as something like:

module.exports = {

   attributes: {

    proj: {
        model:'projet'
    },

    spans: {
        type: 'json'
    },

    before: function() {

       if (this.spans.end < this.proj.end) {
          return this.spans.end;
       } else {
          return this.proj.end;
       }

    },

    after: function() {

       if (this.spans.start > this.proj.start) {
          return this.spans.start;
       } else {
          return this.proj.start;
       }

    }



}

In instance methods (like before and after here), this refers to the entire instance object. You'll want to enhance that code with checks to make sure that this.proj is an object (i.e., that it was populated with ProjetSpan.find({}).populate('project')), and that this.spans.end and this.spans.start actually exist (since Waterline doesn't validate embedded JSON).

sgress454
  • 24,870
  • 4
  • 74
  • 92
  • thank you :) For the object check, I've made `this.proj != null && typeof this.proj === 'object'` but what about `spans` ? At this state is it an object, an array, or something else ? – DestyNova Mar 07 '14 at 09:17
  • "spans" will be whatever JSON type you set it to; most likely an object or array. Unfortunately those are both `typeof` "object", but you can use `sails.util.isArray()` to test for arrays (`sails.util` wraps Lodash). – sgress454 Mar 07 '14 at 15:25
  • Cool thx :) ! I changed my models so following the recommendations, but at some point, what about deep associations test ? like `if ((this.projCollab != null && typeof this.projCollab === 'object') && (this.projCollab.proj != null && typeof this.projCollab.proj === 'object')) { if (this.end < this.projCollab.proj.end) return this.end; else return this.projCollab.proj.end; }` in a `before` function ? I know we can't make I for now, I've done some change for that, but It's still needed in some situations like this one.. – DestyNova Mar 19 '14 at 18:49