在 hasOne 关系中包含相关模型
Include related model in an hasOne relation
我有两个模型:Account
和 Customer
都有一个电子邮件地址。
Account
可以没有 Customer
,Customer
可以没有 Account
。
但是,Account
应该 return 相关的 Customer
记录(如果存在)。
我正在考虑通过使用两个记录(电子邮件地址)中可用的唯一标识符作为 foreignKey 在 Account
上创建 hasOne
关系来做到这一点。
不幸的是,这不起作用。
这些是我的模型:
帐号
...
"properties": {
"username": {
"type": [
"string"
]
},
"email": {
"type": "string"
}
},
"validations": [],
"relations": {
"customer": {
"type": "hasOne",
"model": "Customer",
"foreignKey": "email"
}
}
...
客户
...
"properties": {
"name": {
"type": [
"string"
]
},
"email": {
"type": "string"
}
},
"validations": [],
"relations": {}
...
通过调用 /api/account?filter={"include": ["customer"]}
我没有得到任何附加信息。
我不明白是外键问题还是关系问题。
你的模型定义的很好。
确保您在数据库中有包含现有电子邮件的客户实例。
其余 api 调用的正确是:/api/account?filter[include]=customer
更新
由于关系,环回会覆盖 email
的类型。 hasOne
关系应该在 id
外键而不是任何其他字段上设置。
所以如果你想解决这个问题,你需要在 account
定义的属性部分添加以下内容:
"id": false,
"email": {
"type": "string",
"id": true
}
foreignKey
字段只是关系的别名。拥有 email
属性 并将 email
设置为 foreignKey
不会在两者之间创建任何类型的 link。
然后,只需使用 REST API 实例化模型、设置关系并获取数据
创建一个帐户
POST api/accounts/
{
"email": "account@bar.com"
}
创建相关客户
POST api/accounts/1/foreignKey
{
"email": "customer@bar.com"
}
获取帐户并包含相关客户
GET api/accounts/1?filter[include]=foreignKey
您可以在返回请求的实例之前使用 afterRemote hook 进行编组。
但是这不会是自动的,即您仍然需要为 link 这两个实例一起提供某种 ID。在您的情况下,如果电子邮件是这样的 ID,那么您只需搜索与帐户实例具有相同电子邮件的客户实例。
优点是您不需要为查询提供任何额外的过滤器或任何其他内容。
例如
Account.afterRemote('find', function(ctx, modelInstance, next) {
// Here you can check if the Account instance has a Customer instance
// via a regular find or findById, and if you do find the related instance
// you can add the data to ctx.result, which is the object that will be returned.
Customer.find({where:{email: modelInstance.email}}, addCustomerDetails);
function addCustomerDetails(err, linkedCustomer) {
// Add the Customer to the Account instance here
ctx.result.customer = linkedCustomer;
next();
}
});
当然,您可以在 Customer afterRemote 挂钩中执行相同的操作,但要搜索 linked Account 实例电子邮件。
我有两个模型:Account
和 Customer
都有一个电子邮件地址。
Account
可以没有 Customer
,Customer
可以没有 Account
。
但是,Account
应该 return 相关的 Customer
记录(如果存在)。
我正在考虑通过使用两个记录(电子邮件地址)中可用的唯一标识符作为 foreignKey 在 Account
上创建 hasOne
关系来做到这一点。
不幸的是,这不起作用。
这些是我的模型:
帐号
...
"properties": {
"username": {
"type": [
"string"
]
},
"email": {
"type": "string"
}
},
"validations": [],
"relations": {
"customer": {
"type": "hasOne",
"model": "Customer",
"foreignKey": "email"
}
}
...
客户
...
"properties": {
"name": {
"type": [
"string"
]
},
"email": {
"type": "string"
}
},
"validations": [],
"relations": {}
...
通过调用 /api/account?filter={"include": ["customer"]}
我没有得到任何附加信息。
我不明白是外键问题还是关系问题。
你的模型定义的很好。
确保您在数据库中有包含现有电子邮件的客户实例。
其余 api 调用的正确是:/api/account?filter[include]=customer
更新
由于关系,环回会覆盖 email
的类型。 hasOne
关系应该在 id
外键而不是任何其他字段上设置。
所以如果你想解决这个问题,你需要在 account
定义的属性部分添加以下内容:
"id": false,
"email": {
"type": "string",
"id": true
}
foreignKey
字段只是关系的别名。拥有 email
属性 并将 email
设置为 foreignKey
不会在两者之间创建任何类型的 link。
然后,只需使用 REST API 实例化模型、设置关系并获取数据
创建一个帐户
POST api/accounts/
{
"email": "account@bar.com"
}
创建相关客户
POST api/accounts/1/foreignKey
{
"email": "customer@bar.com"
}
获取帐户并包含相关客户
GET api/accounts/1?filter[include]=foreignKey
您可以在返回请求的实例之前使用 afterRemote hook 进行编组。
但是这不会是自动的,即您仍然需要为 link 这两个实例一起提供某种 ID。在您的情况下,如果电子邮件是这样的 ID,那么您只需搜索与帐户实例具有相同电子邮件的客户实例。
优点是您不需要为查询提供任何额外的过滤器或任何其他内容。
例如
Account.afterRemote('find', function(ctx, modelInstance, next) {
// Here you can check if the Account instance has a Customer instance
// via a regular find or findById, and if you do find the related instance
// you can add the data to ctx.result, which is the object that will be returned.
Customer.find({where:{email: modelInstance.email}}, addCustomerDetails);
function addCustomerDetails(err, linkedCustomer) {
// Add the Customer to the Account instance here
ctx.result.customer = linkedCustomer;
next();
}
});
当然,您可以在 Customer afterRemote 挂钩中执行相同的操作,但要搜索 linked Account 实例电子邮件。