【问题标题】:Add multiple records to model's collection Sailsjs将多条记录添加到模型的集合 Sailsjs
【发布时间】:2014-09-09 20:23:56
【问题描述】:

我的 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();
}

当我发布到事件/创建时,我得到这个结果:http://pastebin.com/PMiqBbfR

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

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

我花了很多时间尝试调试它,所以任何帮助都将不胜感激!

【问题讨论】:

    标签: javascript sails.js waterline


    【解决方案1】:

    您的实现存在一些问题,但主要问题是您将某些方法(即 .save().findOrCreate as 同步方法)处理为(例如所有 Waterline 方法)异步,需要回调。因此,您实际上是在并行运行一堆代码,而不是等待它完成后再返回。

    此外,由于您似乎正在尝试用这个新列表替换当前事件标签,因此您提出的方法有点过度设计-您不不需要使用event.tags.addevent.tags.remove。您可以使用普通的旧 update

    所以你可以将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 here 的完整文档。

    如果您想坚持使用.add.remove 的实现,您仍然希望使用async.map,并在done 方法中执行其余逻辑。你不需要两个.save 电话;只需先运行所有.add.remove 代码,然后运行一个.save(mainCb) 来完成它。

    我不知道你想通过从currentTags(直接引用event.tags)中删除.add.remove 方法来完成什么,但它不会起作用并且只会在以后造成混乱!

    【讨论】:

    • 感谢您的帮助。我有一种感觉,这是由于基于我在网上找到的异步方法造成的。我对异步/同步方法和回调仍然很陌生,在接受您的建议后,我仍然遇到错误并且有点困惑。我在这里问了一个后续问题stackoverflow.com/questions/25800157/…
    猜你喜欢
    • 2016-05-17
    • 2019-09-15
    • 2014-12-02
    • 2014-06-17
    • 1970-01-01
    • 2016-04-29
    • 2015-09-05
    • 1970-01-01
    • 2021-01-21
    相关资源
    最近更新 更多