如果不存在sails.js,则创建并添加到集合

时间:2015-04-17 23:18:59

标签: node.js promise sails.js waterline

我对sails.js和node.js都很陌生,所以这可能不是Sails特定的问题,但我创建了一个用户和标记模型,以便用户有很多标签,反之亦然。用户模型的相关属性是:

# 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 );
    }
  });
},

标签模型:

name     : { type: 'string', required: true, index: true },
users    : { collection : 'User', via: 'tags' },

现在,当我运行sails console时,我使用以下测试:

sails> var user = null; User.find().exec( function( err, u ) { user= u[0]; });
undefined
sails> user.add_tag('cataclysmic');
undefined
sails> info: didnt find tag, creating with 2 and cataclysmic

在我按Enter或Ctrl + C并且没有创建Tag之前它会挂起。

同样,我对来自Rails背景的Node和Sails非常陌生,所以它可能是非常愚蠢的东西。此外,如果我没有正确使用承诺,请告诉我,因为我也很新。

更新

Per Travis Webb的建议,我试图转换为findOrCreate,但它仍然没有悲伤地工作:

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
},

使用与上面相同的sails console命令来调用add_tag()我得到undefined并且没有执行任何日志语句。特拉维斯,我在这个实施中做错了吗?

最终更新

我使用Jason的答案来创建我的最终答案:

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 );
},

我的代码没有显示任何错误的原因是我在Tag.js中使用了生命周期回调来在每次更新时增加优先级计数器,如下所示:

afterValidate: function() {
 this.priority++;
}

当我应该像这样调用链中的下一个回调时:

afterValidate: function( values, cb ) {
  values.priority++;
  cb();
}

您不会考虑来自Rails背景的其中一件事:P

1 个答案:

答案 0 :(得分:2)

您错误地使用了findOrCreate

函数定义为.findOrCreate( search criteria, [values, callback] )

您可能需要将您的功能修改为:

add_tag: function( name ) {
  var self = this;

  //for clarity we won't set the user when creating tags, 
  //instead we'll do it in the callback, so its the same for existing and new tags.
  Tag.findOrCreate({ name: name }, { name: name })
  .then( function( tag ){
    tag.users.add( self.id );
    tag.save( sails.log.info );

  });
},