编辑页面

多对多

又称“拥有并属于多个”

概述

#

多对多关联表明,一条记录可以与许多其他记录相关联,反之亦然。这种类型的关联涉及创建连接表来跟踪记录之间多个链接。当 Waterline 检测到两个模型具有通过其via键(见下文)相互指向的集合属性时,它将自动为您构建一个连接表。

via

#

由于您可能希望模型在另一个模型上具有多个多对多关联,因此collection属性上需要一个via键。via键指示多对多关联另一侧的相关属性。

使用UserPet示例,让我们看看如何构建一个架构,其中一个User可以拥有许多Pet记录,而一个Pet可以有多个主人。

// myApp/api/models/User.js
// A user may have many pets
module.exports = {
  attributes: {
    firstName: {
      type: 'string'
    },
    lastName: {
      type: 'string'
    },

    // Add a reference to Pet
    pets: {
      collection: 'pet',
      via: 'owners'
    }
  }
};
// myApp/api/models/Pet.js
// A pet may have many owners
module.exports = {
  attributes: {
    breed: {
      type: 'string'
    },
    type: {
      type: 'string'
    },
    name: {
      type: 'string'
    },

    // Add a reference to User
    owners: {
      collection: 'user',
      via: 'pets'
    }
  }
};

为了将记录关联在一起,使用 Model 方法.addToCollection()。这允许您设置将被关联的记录的主键。

// To add a Pet to a user's `pets` collection where the User has an id of
// 10 and the Pet has an id of 300.
await User.addToCollection(10, 'pets', 300);

您也可以一次添加多个宠物

await User.addToCollection(10, 'pets', [300, 301]);

使用.removeFromCollection()方法移除关联也同样简单。它的工作方式与addToCollection相同

// To remove a User from a pet's collection of owners where the User has an id of
// 10 and the Pet has an id of 300.
await Pet.removeFromCollection(300, 'owners', 10);

您也可以一次移除多个主人

await Pet.removeFromCollection(300, 'owners', [10, 12]);

请注意,从多对多关联的一侧添加或移除关联的记录将自动影响另一侧。例如,使用.addToCollection()将记录添加到User模型记录的pets属性中将立即影响链接的Pet记录的owners属性。

要返回与.find().findOne()检索的记录一起的关联集合,请使用.populate()方法。

主导

#

在大多数情况下,Sails 能够在没有任何输入的情况下为多对多关联创建连接表。但是,如果关联中的两个模型使用不同的数据存储,您可能希望选择哪个模型应该包含连接表。您可以通过在一个关联中的关联之一上设置dominant: true来做到这一点。

请考虑以下模型

// User.js
module.exports = {
  datastore: 'ourMySQL',
  attributes: {
    email: 'string',
    wishlist: {
      collection: 'product',
      via: 'wishlistedBy'
    }
  }
};
// Product.js
module.exports = {
  datastore: 'ourRedis',
  attributes: {
    name: 'string',
    wishlistedBy: {
      collection: 'user',
      via: 'wishlist'
    }
  }
};

在这种情况下,UserProduct记录存在于不同的数据库中。默认情况下,Sails 将任意选择一个数据存储(ourMySQLourRedis)来包含链接Userwishlist属性到ProductwishlistedBy属性的连接表。为了强制连接表存在于ourMySQL数据存储中,您将在wishlist属性定义中添加dominant: true。相反,在wishlistedBy属性中添加dominant: true将导致连接表在ourRedis数据存储中创建。

选择“主导”
#

几个因素可能会影响您在何处创建连接表的决定

是否缺少什么?

如果您发现我们遗漏了什么或可以改进的地方,请遵循此链接并向 sails 仓库提交拉取请求。一旦我们合并它,更改将在下次部署时反映在网站上。

概念