避免重复多态hasAndBelongsToMany通过模型关系

时间:2017-05-16 09:46:00

标签: javascript loopbackjs

我与多态的直通模型有着相当复杂的关系。在应用程序中,有一个标记系统,可以标记用户和另一个模型。为了避免重复的字符串条目,我使用了一个直通模型(TagLink),它包含标签ID,标记的模型名称和标记的实例ID。

所以我有

User --+
       |
       +---> TagLink -----------> Tag
       |      - tagId              - id
Item --+      - taggableId         - text
              - taggableName
                (User or Item)

链接关系为hasAndBelongsToMany。问题是,当我将新标记发布到/items/:id/tags/users/:id/tags时,它会被保存,但我可以使用相同的文本创建任意数量的标记,而不会出现任何错误。

我想要的是,在发布到/items/:id/tags/users/:id/tags后,它会:

  • 创建一个新的标记条目(如果它尚不存在),然后添加一个新的TagLink条目(这是当前行为,但即使已经存在相同的标记)
  • 仅在标记已存在时创建TagLink条目

我想到了两个解决方案:

  • 以某种方式覆盖Tag的create方法以检查是否存在,然后手动创建TagLink条目(如果存在)。如果没有,请默认继续。
  • 使用〜所有CRUD URI公开标记列表(/tags),然后强制使用/{items,users}/:id/tags上的标记ID。

理想情况下,我更喜欢第一个,因为它更透明,并且使API更流畅。

所以,欢迎任何线索!

1 个答案:

答案 0 :(得分:1)

我最终做了第一个解决方案,这非常简单。我们的想法是在引导脚本中替换User.create方法,该方法找到具有相同text的标记,并在找到一个标记时返回它。

module.exports = function(app) {
    var Tag = app.models.Tag;

    // Override Tag.create to avoid duplicates
    Tag.createRaw = Tag.create;
    Tag.create = function(data, token, cb) {
        // Find matching tag
        Tag.findOne({where: {text: data.text}}, (err, tag) => {
            if (err)      cb(err);
            // If the tag is found, return it
            else if (tag) cb(null, tag);
            // Else create it
            else          Tag.createRaw(data, token, cb);
        });
    }
}