【问题标题】:Create unique multikey index via model settings通过模型设置创建唯一的多键索引
【发布时间】:2018-12-19 12:58:52
【问题描述】:

我正在使用 Sails v1.1 -

我按照此处的风帆文档创建了一个多对多的自定义模型关联 - https://sailsjs.com/documentation/concepts/models-and-orm/associations/through-associations

PetUser 模型有两列 petuser,其中每一列都是各自的 id。我想创建一个唯一的多键索引,这意味着不能有两行具有相同的“宠物和用户”组合。意味着第二次调用应该成功,第三次调用应该失败并出现唯一性错误:

await PetUser.create({ user: 1, pet: 33 }); // should succeed
await PetUser.create({ user: 1, pet: 44 }); // should succeed as user/pet combination is different
await PetUser.create({ user: 1, pet: 33 }); // should fail

我尝试将unique: true 添加到下面PetUser 模型上的ownerpet 属性,但只有第一个unique: true 得到尊重。

这是我在myApp/api/models/PetUser.js中的代码

module.exports = {
  attributes: {
    owner: {
      model:'user',
      unique: true
    },
    pet: {
      model: 'pet',
      unique: true
    }
  }
}

【问题讨论】:

    标签: sails.js


    【解决方案1】:

    为了实现类似的行为,我添加了一个组合属性并将其标记为唯一。此外,我添加了 beforeCreatebeforeUpdate 模型钩子,在这些钩子上生成我的组合属性以检查它是否唯一。

    const YourModel = {
    
      attributes: {
        owner: {
          model: 'user',
        },
        pet: {
          model: 'pet',
        },
        petOwner: {
          type: 'string',
          unique: true,
        }
      },
    
      beforeCreate : function(values,cb) {
        // TODO get ids from related records or reset to default on missed relation record if you need it
        const petId = 35;
        const ownerId = 8;
        values.petOwner = `${petId}-${ownerId}`;
        cb();
      },
    
      beforeUpdate : function(values,cb) {
        YourModel.beforeCreate(values, cb)
      },
    };
    
    module.exports = YourModel;
    

    结果当您尝试添加具有相同关系的记录时,您将得到E_UNIQUE,正如您所料。

    【讨论】:

    • 非常感谢 Pavlo 对我问题的关注。这似乎是一种解决方法,如果我无法弄清楚,我会使用它。如果我弄清楚了,我会与你分享。 :) 或者你确定这是不可能的?
    • @Noitidart 我只想分享我的经验 :) 我想这是一种解决方法。在半年前的有限时间内,我还没有为类似的任务找到更好的解决方案,所以这是我在 Sails.js 上的一个项目的产品:)
    • 非常感谢@Pavlo,您的经验非常宝贵。它绝对有很大帮助。多个addToCollection/removeFromCollection怎么办?我们要一一PetUser.create对吧?喜欢这里 - stackoverflow.com/a/53860856/1828637
    • @Noitidart 坦率地说,我尽量避免在 Waterline 中使用关系,但我真的很喜欢 Laravel Eloquent 中的关系。当我尝试使用addToCollection 时,我一次只为一条记录这样做。我没有遇到需要为真实项目中的多条记录执行此操作的情况
    • 我不知道。为了弄清楚,我通常会去资源。我知道这是水线,方法名称是 create each,所以我需要在水线包中的某个地方找到 createEach 方法声明。当我打开 node_modules/waterline 时,我只看到 lib 文件夹看起来合适。在里面我可以看到一个文件夹waterline,子文件夹methods 在那里我看到create-each.js。所以在检查后我发现node_modules/waterline/lib/waterline/methods/create-each.js:292 行,我可以看到这个查询运行它是一种算法,但多次调用适配器。
    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 2010-12-07
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多