我有一个模型“用户”,与“主题”有多对一的关系。
user.js的
attributes: {
subject: { model: 'subject' },
}
Subject.js
attributes: {
name: { type: 'string', unique: true, required: true },
}
当我为用户“/ user”调用蓝图创建函数并传入数据时:
{
"name":"Test",
"subject":{"name":"Do Not Allow"}
}
它创建用户并创建主题。但是我不想允许创建主题,我只希望能够附加现有主题。例如,我希望它拒绝使用上述数据创建的主题,但允许使用以下数据附加主题。
{
"name":"Test",
"subject":1
}
我尝试添加一个策略(如下所示),但这只会阻止使用URL“/ subject”创建主题,而不是上面显示的嵌套创建。
'SubjectController':{
'create':false
}
修改 为了帮助理解这里发生的事情,这是它正在经历的生命周期过程:
Before Validation of Subject
After Validation of Subject
Before Creating Subject
After Creating Subject
Before Validation of User
After Validation of User
Before Creating User
Before Validation of User
After Validation of User
After Creating User
正如您所看到的那样,在验证或创建用户之前,它正在验证和创建主题。
答案 0 :(得分:2)
您希望在调用蓝图创建路径时避免创建关联对象。
制定政策(我将其命名为checkSubjectAndHydrate
)并将其添加到policies.js
文件中:
// checkSubjectAndHydrate.js
module.exports = function (req, res, next) {
// We can create a user without a subject
if (_.isUndefined(req.body.subject)) {
return next();
}
// Check that the subject exists
Subject
.findOne(req.body.subject)
.exec(function (err, subject) {
if (err) return next(err);
// The subject does not exist, send an error message
if (!subject) return res.forbidden('You are not allowed to do that');
// The subject does exist, replace the body param with its id
req.body.subject = subject.id;
return next();
});
};
// policies.js
module.exports.policies = {
UserController: {
create: 'checkSubjectAndHydrate',
update: 'checkSubjectAndHydrate',
}
};
答案 1 :(得分:0)
您可以为主题创建自定义类型,并在模型中添加逻辑。我不是百分百肯定我理解附着有时是部分,但也许这可能会有所帮助:
模型/ user.js的
module.exports = {
schema: true,
attributes: {
name: {
type: 'string'
},
subject: {
type: 'json',
myValidation: true
}
},
types: {
myValidation: function(value) {
// add here any kind of logic...
// for example... reject if someone passed name key
return !value.name;
}
}
};
您可以在页面底部http://sailsjs.org/documentation/concepts/models-and-orm/validations找到更多信息。
如果我完全错过了这一点......第二个选项是将beforeCreate和beforeUpdate生命周期回调添加到你的模型中:
模型/ user.js的
module.exports = {
schema: true,
attributes: {
name: {
type: 'string'
},
subject: {
type: 'json'
}
},
beforeCreate: function (values, cb) {
// for example... reject creating of subject if anything else then value of 1
if (values.subject && values.subject !== 1) return cb('make error obj...');
cb();
},
beforeUpdate: function (values, cb) {
// here you can add any kind of logic to check existing user or current update values that are going to be updated
// and allow it or not
return cb();
}
};
通过使用它,你可以使用一个逻辑来创建,另一个用于更新...等...
您可以在此处找到更多信息:http://sailsjs.org/documentation/concepts/models-and-orm/lifecycle-callbacks
修改强>
意识到你在关系方面遇到了麻烦,在上面的例子中我认为你正在处理类型json ......
module.exports = {
schema: true,
attributes: {
name: {
type: 'string'
},
subject: {
model: 'subject'
}
},
beforeValidate: function (values, cb) {
// subject is not sent at all, so we just go to next lifecycle
if (!values.subject) return cb();
// before we update or create... we will check if subject by id exists...
Subject.findOne(values.subject).exec(function (err, subject) {
// subject is not existing, return an error
if (err || !subject) return cb(err || 'no subject');
//
// you can also remove subject key instead of sending error like this:
// delete values.subject;
//
// subject is existing... continue with update
cb();
});
}
};
答案 2 :(得分:0)
您应该传递主题ID(例如1
)而不是包含主题名称的对象(例如{ name: 'Hello, World!' }
),因为它不一定是唯一的。
如果它是唯一的,您应该在beforeValidate
内用id替换该对象。
// User.js
module.exports = {
...
beforeValidate: function (users, callback) {
// users = [{
// "name":"Test",
// "subject":{"name":"Do Not Allow"}
// }]
async.each(users, function replaceSubject(user, next) {
var where = {};
if (_.isObject(user.subject) && _.isString(user.subject.name)) {
where.name = user.subject.name;
} else if(_.isInteger(user.subject)) {
where.id = user.subject;
} else {
return next();
}
// Check the existence of the subject
Subject
.findOne(where)
.exec(function (err, subject) {
if (err) return next(err);
// Create a user without a subject if it does not exist
user.subject = subject? subject.id : null;
next();
});
}, callback);
// users = [{
// "name":"Test",
// "subject":1
// }]
}
};