title: Create and Add to collection if not exists sails.js
body: <p>I'm pretty new to <a href="http://sailsjs.org" rel="nofollow noreferrer">sails.js</a> as well as node.js so this may not be a Sails specific question, but I've created a User and Tag model such that a User has many tags and vice versa. The relevant attributes of user model are:</p>
  <pre><code># models/User.js
  tags      : { collection: 'Tag', via: 'users' },
  add_tag: function( name ) {
    var self = this;
    Tag.findOne({ name: name })
    .then( function( found ){
      if( found ) {
        sails.log.info('found tag ' + found)
        found.users.add( self.id );
        self.save( sails.log.info );
      } else {
        sails.log.info('didnt find tag, creating with ' + self.id + ' and ' + name);
        Tag.create({ name: name, users: [ self.id ] }).exec( console.log );
      }
    });
  },
  </code></pre>
  <p>And of the Tag model:</p>
  <pre><code>name     : { type: 'string', required: true, index: true },
  users    : { collection : 'User', via: 'tags' },
  </code></pre>
  <p>Now when I run <code>sails console</code> I use the following test:</p>
  <pre><code>sails&gt; var user = null; User.find().exec( function( err, u ) { user= u[0]; });
  undefined
  sails&gt; user.add_tag('cataclysmic');
  undefined
  sails&gt; info: didnt find tag, creating with 2 and cataclysmic
  </code></pre>
  <p>And there it hangs until I press Enter or Ctrl+C and no Tag is created.</p>
  <p>Again I'm very new to Node and Sails coming from a Rails background so it could be something very stupid. Also if I'm not using promises correctly please let me know, since I'm pretty new to those as well.</p>
  <h1>Update</h1>
  <p>Per Travis Webb's suggestion, I tried to convert to <code>findOrCreate</code> and it's still not working sadly:</p>
  <pre><code>add_tag: function( name ) {
    var self = this;
    Tag.findOrCreate({ name: name })
    .then( function( tags ){
      sails.log.info( JSON.stringify(tags) );
      return tags;
    }).spread( function( tag ){ // should get the first matching tag
      sails.log.info( JSON.stringify(tag) );
      Tag.update( { name: tag }, { user: self.id } )
      .exec( sails.log.info );
    }).catch( sails.log.error ); //no errors are logged either
  },
  </code></pre>
  <p>Using the same <code>sails console</code> commands as above to call <code>add_tag()</code> I just get <code>undefined</code> and none of the log statements are executed. Travis, did I do something wrong in this implementation?</p>
  <h1>Final Update</h1>
  <p>I used Jason's answer below to create my final answer:</p>
  <pre><code>add_tag: function( name ) {
    var self = this;
    Tag.findOrCreate({ name: name }, { name: name })
    .then( function( tag ){
      tag.users.add( self.id );
      tag.save( sails.log.info );
    }).catch( sails.log.error );
  },
  </code></pre>
  <p>The reason my code was not showing any errors is that I used a lifecycle callback in Tag.js to increment a priority counter each time it is updated like so:</p>
  <pre><code>afterValidate: function() {
   this.priority++;
  }
  </code></pre>
  <p>When I should have been calling the next callback in the chain like so:</p>
  <pre><code>afterValidate: function( values, cb ) {
    values.priority++;
    cb();
  }
  </code></pre>
  <p>One of the things you don't think about coming from a Rails background :P</p>