在 Loopback 上,如何在使用从访问令牌获取的 user_id 时执行 Upsert 事件?
On Loopback, how to perform an Upsert event while using the user_id obtained from access token?
假设您有两个表:CARS
和 VOTES
。
现在您想让您的用户在汽车中投票。他们可以投票给一辆新车或改变他们之前的投票,但没有用户可以两次投票给相同的护理。
VOTE-MODEL
car_id
user_id
vote_value
您将如何为该模型设置更新插入过程?请记住,Upsert 方法不接受远程挂钩(在保存之前),这将阻止您从访问令牌中获取 user_id
。
以下是我尝试过但没有奏效的一些方法:
尝试 1
'use strict';
module.exports = function (Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if (context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
Votes.upsertWithWhere({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, context.instance, function (err, cb) {
if (err) return next(err);
console.log('cb', cb);
});
}
}
}
});
};
尝试 2
'use strict';
module.exports = function(Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if(context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
Votes.find({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, function(err, cb) {
if (!cb.length) {
// If it does not find anything, go next, accept post
next();
} else {
// Otherwise update record
Votes.updateAll({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, context.instance, function(err, cb) {
console.log('cb', cb);
});
}
});
}
}
}
});
};
这两种尝试的问题是,似乎没有为 Upsert 或 Udpate 执行代码。
它被命名为操作钩子而不是远程钩子。
顺便说一句,您的第一次尝试应该像这样:
module.exports = function (Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if (context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
}
return next();
}else {
Votes.count({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id,
vote_value: context.instance.vote_value
}
}, function(err, count){
if(err) return next(err);
if(count > 0) next(SuitableError);
next();
});
}
}
});
};
您只需修改用户id,即可完成操作。无需额外 update/upsert.
并且如果这不是新实例,则检查具有相同标准的先前投票,如果存在则拒绝它,否则允许它。
也有一个简单的解决方法,不用hooks
Votes.vote = function(data, options, cb){
var userId = options && options.accessToken && options.accessToken.userId;
if(!userId){
return cb(UserNotFound); //return error
}
Votes.upsertWithWhere({
car_id: data.car_id,
user_id: userId
}, {
car_id: data.car_id,
user_id: userId,
vote_value: data.vote_value
}, function(err, result){
if(err) return cb(err);
cb(null, result);
});
};
Votes.remoteMethod('vote', {
accepts: [
{
arg: 'data',
type: 'Object',
required: true,
http: {source: 'body'}
},
{
arg: 'options',
type: 'Object',
http: "optionsFromRequest"
}
],
returns: {root: true, type: 'object'},
http: {verb: 'post', status: 201, path: '/vote'}
});
假设您有两个表:CARS
和 VOTES
。
现在您想让您的用户在汽车中投票。他们可以投票给一辆新车或改变他们之前的投票,但没有用户可以两次投票给相同的护理。
VOTE-MODEL
car_id
user_id
vote_value
您将如何为该模型设置更新插入过程?请记住,Upsert 方法不接受远程挂钩(在保存之前),这将阻止您从访问令牌中获取 user_id
。
以下是我尝试过但没有奏效的一些方法:
尝试 1
'use strict';
module.exports = function (Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if (context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
Votes.upsertWithWhere({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, context.instance, function (err, cb) {
if (err) return next(err);
console.log('cb', cb);
});
}
}
}
});
};
尝试 2
'use strict';
module.exports = function(Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if(context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
Votes.find({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, function(err, cb) {
if (!cb.length) {
// If it does not find anything, go next, accept post
next();
} else {
// Otherwise update record
Votes.updateAll({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id
}
}, context.instance, function(err, cb) {
console.log('cb', cb);
});
}
});
}
}
}
});
};
这两种尝试的问题是,似乎没有为 Upsert 或 Udpate 执行代码。
它被命名为操作钩子而不是远程钩子。
顺便说一句,您的第一次尝试应该像这样:
module.exports = function (Votes) {
Votes.observe('before save', function setAutoData(context, next) {
if (context.instance) {
if (context.isNewInstance) {
if (context.options.accessToken) {
context.instance.user_id = context.options.accessToken.userId;
}
return next();
}else {
Votes.count({
where: {
car_id: context.instance.car_id,
user_id: context.instance.user_id,
vote_value: context.instance.vote_value
}
}, function(err, count){
if(err) return next(err);
if(count > 0) next(SuitableError);
next();
});
}
}
});
};
您只需修改用户id,即可完成操作。无需额外 update/upsert.
并且如果这不是新实例,则检查具有相同标准的先前投票,如果存在则拒绝它,否则允许它。
也有一个简单的解决方法,不用hooks
Votes.vote = function(data, options, cb){
var userId = options && options.accessToken && options.accessToken.userId;
if(!userId){
return cb(UserNotFound); //return error
}
Votes.upsertWithWhere({
car_id: data.car_id,
user_id: userId
}, {
car_id: data.car_id,
user_id: userId,
vote_value: data.vote_value
}, function(err, result){
if(err) return cb(err);
cb(null, result);
});
};
Votes.remoteMethod('vote', {
accepts: [
{
arg: 'data',
type: 'Object',
required: true,
http: {source: 'body'}
},
{
arg: 'options',
type: 'Object',
http: "optionsFromRequest"
}
],
returns: {root: true, type: 'object'},
http: {verb: 'post', status: 201, path: '/vote'}
});