Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将多个记录添加到模型';s系列帆船_Javascript_Sails.js_Waterline - Fatal编程技术网

Javascript 将多个记录添加到模型';s系列帆船

Javascript 将多个记录添加到模型';s系列帆船,javascript,sails.js,waterline,Javascript,Sails.js,Waterline,我的Sailsjs应用程序中有以下模型,它们之间存在多对多关系: event.js: attributes: { title : { type: 'string', required: true }, description : { type: 'string', required: true }, location : { type: 'string', required: true }, maxMembers : { type: 'integer', required: true }

我的Sailsjs应用程序中有以下模型,它们之间存在多对多关系:

event.js:

attributes: {
 title : { type: 'string', required: true },
 description : { type: 'string', required: true },
 location : { type: 'string', required: true },
 maxMembers : { type: 'integer', required: true },
 currentMembers : { collection: 'user', via: 'eventsAttending', dominant: true },
 creator : { model: 'user', required: true },
 invitations : { collection: 'invitation', via: 'eventID' },
 tags : { collection: 'tag', via: 'taggedEvents', dominant: true },
 lat : { type: 'float' },
 lon : { type: 'float' },
},
tags.js:

attributes: {
 tagName : { type: 'string', unique: true, required: true },
 taggedEvents : { collection: 'event', via: 'tags' },
},
根据文档,这种关系看起来是正确的。我在tag.js中有以下方法,该方法接受标记字符串数组和事件id,并且应该添加或删除传入的标记:

modifyTags: function (tags, eventId) {
var tagRecords = [];

_.forEach(tags, function(tag) {
    Tag.findOrCreate({tagName: tag}, {tagName: tag}, function (error, result) {
        tagRecords.push({id: result.id})
    })
})

Event.findOneById(eventId).populate('tags').exec(function(error, event){
    console.log(event)
    var currentTags = event.tags;
    console.log(currentTags)
    delete currentTags.add;
    delete currentTags.remove;

    if (currentTags.length > 0) {
      currentTags = _.pluck(currentTags, 'id');
    }

    var modifiedTags = _.pluck(tagRecords, 'id');
    var tagsToAdd = _.difference(modifiedTags, currentTags);
    var tagsToRemove = _.difference(currentTags, modifiedTags);
    console.log('current', currentTags)
    console.log('remove', tagsToRemove)
    console.log('add', tagsToAdd)

    if (tagsToAdd.length > 0) {
      _.forEach(tagsToAdd, function (tag) {
        event.tags.add(tag);
      })
        event.save(console.log)
    }

    if (tagsToRemove.length > 0) { 
      _.forEach(tagsToRemove, function (tagId) {
         event.tags.remove(tagId)
      })
       event.save()
    }      
})
}
以下是从事件模型调用方法的方式:

afterCreate: function(record, next) {
  Tag.modifyTags(tags, record.id)
  next();
}
当我发布到事件/创建时,我得到以下结果:

看起来方法调用本身是循环的,而不仅仅是tagsToAdd或tagsToRemove数组。更令人困惑的是,在事件的最后一个日志中,事件似乎有正确的标记。然而,当我随后发布到event/1时,tags数组是空的。我还尝试在每次
.add()
之后立即保存,但仍然得到类似的结果

理想情况下,我希望循环使用tagsToAdd和tagsToRemove数组,在模型集合中修改它们的ID,然后在模型上调用一次
.save()


我已经花了大量的时间调试这个,所以任何帮助都将不胜感激

您的实现存在一些问题,但主要问题是您将某些方法视为同步方法,而这些方法(与所有水线方法一样)是异步的,需要回调。因此,您可以有效地并行运行一组代码,而不必等到代码完成后再返回

此外,由于您试图用这个新列表替换当前事件标记,因此您提出的方法有点过于复杂--您不需要使用
event.tags.add
event.tags.remove
。您只需使用普通的旧
更新

因此,您可能可以将
modifyTags
方法重写为:

modifyTags: function (tags, eventId, mainCb) {

  // Asynchronously transform the `tags` array into an array of Tag records
  async.map(tags, function(tag, cb) {
    // For each tag, find or create a new record.
    // Since the async.map `cb` argument expects a function with 
    // the standard (error, result) node signature, this will add
    // the new (or existing) Tag instance to the resulting array.
    // If an error occurs, async.map will exit early and call the
    // "done()" function below
    Tag.findOrCreate({tagName: tag}, {tagName: tag}, cb);
  }, function done (err, tagRecords) {
    if (err) {return mainCb(err);}
    // Update the event with the new tags
    Event.update({id: eventId}, {tags: tagRecords}).exec(mainCb);
  });

}
参见
async.map
的完整文档

如果您想继续使用
.add
.remove
实现,您仍然需要使用
async.map
,并在
done
方法中执行其余逻辑。您不需要两次
。保存
调用;只需运行所有的
。添加
。首先删除
代码,然后执行单个
。保存(mainCb)
,即可完成


我不知道删除
。添加
。从
currentTags
(这是对
事件.标记的直接引用)中删除
方法想要实现什么,但它不起作用,只会在以后引起混乱

谢谢你的帮助。我觉得这是由于基于我在网上发现的异步方法造成的。我对异步/同步方法和回调仍然非常陌生,在接受了您的建议之后,我仍然会遇到错误,并且有点困惑。我在这里问了一个后续问题