与 SailsJS 的多态关联
Polymorphic associations with SailsJS
我使用 sailsJS 构建了一个 REST API,它利用了蓝图。
我的设计有很多资源,其中一个是资产资源:
Asset ( id, type, owner_type, owner_id, url);
这将作为入口点为系统中的任何其他资源托管多个资产。
即。
用户资源可以有多个图像和一个视频。所有这些记录都存储在资产资源下。
Asset ( id, type, owner_type, owner_id, url);
Asset ( 1, 'image', 'User', 1, 'http://path.to.image.com/abc.jpg');
Asset ( 2, 'video', 'User', 1, 'https://youtube.com/sdasd');
Asset ( 3, 'image', 'BlogPost', 20, 'http://path.to.image.com/blogpost.jpg');
所以理想情况下,当我通过 ID 获取用户或获取所有用户时,我更愿意获取该对象的相关资产。
如果我对 GetOne 和 GetAll 实施这两种方法,则可以准备响应,但在使用蓝图时它有点模糊。
如果我的理解是正确的,你有用户模型,然后你有资产模型。
用户模型看起来像
//User.js
module.exports={
assets:{collection:'Asset',via:'owner_id'}
}
资产模型应该看起来像
module.exports={
type:'string',
owner_type:'string',
owner_id:{model:'User'},
url:'string'
}
您将无法直接使用蓝图,但您可以这样做:
//UserController.js
module.exports={
findOne:function(req,res){
User.findOne(req.param.id).populate('assets',{owner_type:'User'}).exec(function(data){res.json(data)});
},
find:function(req,res){
User.find().populate.....//same idea
}
}
这个populate参数{owner_type}是populate options,让它只填充资产集合,其中有owner_type是"User",也可以指定limit,就像文档 here 一样,不幸的是我没有找到官方文档,sails 和 waterline 仍然是一个年轻的框架,有很多不清楚的文档和东西,但我认为你已经做出了正确的选择来使用它。让我知道是否有帮助。
编辑:这只适用于用户,如果您有博客模型也需要填充它,那么您可以手动完成
//Blog.js
var Promise=require('bluebird');
module.exports={
findOne:function(req,res){
Promise.all([Blog.findOne(req.param.id),
Asset.find({owner_id:req.param.id,owner_type:'blog'})])
.spread(function(blog,assets){
blog.assets=assets
return req.json(blog);
})
}
}
试试我的多态、深入且包容的 populat 钩子:sails-hook-deep-orm 它解决了多态关联等问题。
特点:
- 多态种群
- 例如:
js let Results = await Status.find().populate('*');
- 深层人群
- 例如:
js let Results = await Person.find().populate('home.occupants.statuses.*');
- 包容性标准人群
- 例如:
js let Results = await Person.find().populate('home.occupants&state.statuses&phones.*&network');
- Deep Wild Object 和 Array Utils
- 例如:
js sails.hooks.deeporm.wild.get(Records, "*.home.occupants.*.phones.0.number");
我使用 sailsJS 构建了一个 REST API,它利用了蓝图。
我的设计有很多资源,其中一个是资产资源:
Asset ( id, type, owner_type, owner_id, url);
这将作为入口点为系统中的任何其他资源托管多个资产。
即。
用户资源可以有多个图像和一个视频。所有这些记录都存储在资产资源下。
Asset ( id, type, owner_type, owner_id, url);
Asset ( 1, 'image', 'User', 1, 'http://path.to.image.com/abc.jpg');
Asset ( 2, 'video', 'User', 1, 'https://youtube.com/sdasd');
Asset ( 3, 'image', 'BlogPost', 20, 'http://path.to.image.com/blogpost.jpg');
所以理想情况下,当我通过 ID 获取用户或获取所有用户时,我更愿意获取该对象的相关资产。
如果我对 GetOne 和 GetAll 实施这两种方法,则可以准备响应,但在使用蓝图时它有点模糊。
如果我的理解是正确的,你有用户模型,然后你有资产模型。
用户模型看起来像
//User.js
module.exports={
assets:{collection:'Asset',via:'owner_id'}
}
资产模型应该看起来像
module.exports={
type:'string',
owner_type:'string',
owner_id:{model:'User'},
url:'string'
}
您将无法直接使用蓝图,但您可以这样做:
//UserController.js
module.exports={
findOne:function(req,res){
User.findOne(req.param.id).populate('assets',{owner_type:'User'}).exec(function(data){res.json(data)});
},
find:function(req,res){
User.find().populate.....//same idea
}
}
这个populate参数{owner_type}是populate options,让它只填充资产集合,其中有owner_type是"User",也可以指定limit,就像文档 here 一样,不幸的是我没有找到官方文档,sails 和 waterline 仍然是一个年轻的框架,有很多不清楚的文档和东西,但我认为你已经做出了正确的选择来使用它。让我知道是否有帮助。
编辑:这只适用于用户,如果您有博客模型也需要填充它,那么您可以手动完成
//Blog.js
var Promise=require('bluebird');
module.exports={
findOne:function(req,res){
Promise.all([Blog.findOne(req.param.id),
Asset.find({owner_id:req.param.id,owner_type:'blog'})])
.spread(function(blog,assets){
blog.assets=assets
return req.json(blog);
})
}
}
试试我的多态、深入且包容的 populat 钩子:sails-hook-deep-orm 它解决了多态关联等问题。
特点:
- 多态种群
- 例如:
js let Results = await Status.find().populate('*');
- 例如:
- 深层人群
- 例如:
js let Results = await Person.find().populate('home.occupants.statuses.*');
- 例如:
- 包容性标准人群
- 例如:
js let Results = await Person.find().populate('home.occupants&state.statuses&phones.*&network');
- 例如:
- Deep Wild Object 和 Array Utils
- 例如:
js sails.hooks.deeporm.wild.get(Records, "*.home.occupants.*.phones.0.number");
- 例如: