假设我在Loopback中有三个模型:Reader,Book和Note。 Reader是User的一个实例,可以登录。关系就是这样:
我想要实现的是使用属于Book和Reader的填充Notes来查询已登录Reader的所有Books。
Api电话会是这样的:
/api/reader/me/books?filter[include]=notes
但这会返回属于本书的所有笔记,无论它们属于阅读器。我可以在api调用中添加另一个过滤器,但我需要在服务器端过滤Notes,以便读者无法访问其他读者的注释。
我尝试将此访问控制添加到Book模型:
{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "__get__notes"
}
这个acl to Note model
[
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
}, {
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "*"
}
]
适用于此类调用
/api/reader/me/books/<bookId>/notes
但不适用于包含过滤器的第一次调用。我该怎么办才能获得书中填写的读者笔记?
任何帮助都非常感激。
答案 0 :(得分:0)
要实现这一点,您必须创建一个远程方法。您必须在应用程序级别应用过滤器。
假设用户详细信息存储在User
模型
module.exports = function(Reader){
var async = require('async');
Reader.fetchBooks = function(userId, callback){
var app = this.app;
var updatedReaderList = [];
Reader.find({
where: {userId: userId },
include: {relation: "books"}
}, function(err, readerList){
if(err){
return callback(err);
}
if(readerList){
if(readerList.length){
var series = [];
readerList.forEach(function(reader){
var readerObj = reader.toJSON();
updatedReaderList.push(readerObj);
if(readerObj.books){
readerObj.books.forEach(function(book){
series.push(function(callback){
fetchNotes(app, book, readerObj.id, callback);
});
}
}
});
//Now save the data in series..
async.series(series, function(err){
if(err){
callback(err);
}else{
//Now send the callback
callback(null, updatedReaderList);
}
});
}else{
callback(null, [])
}
}else{
callback(null, [])
}
});
};
var fetchNotes = function(app, book, readerId, callback){
var Note = app.models.Note;
//Fetch only those note whose reader id belongs to current reader and book belongs to same one.
Note.find({
where: {
readerId: readerId,
bookId: book.id
}
}, function(err, noteList){
if(err){
return callback(err);
}else{
if(noteList){
book.notes = noteList;
}
}
});
};
}
现在,您可以限制所有其他方法,只需允许此远程方法。
{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "fetchBooks"
}
注意:您可以使用promise删除回调地狱。