Waterline/SailsJs防止嵌套(关系)保存模型
Waterline/SailsJs prevent nested (relationship) save of model
我有一个与"Subject"具有多对一关系的"User"模型。
User.js
attributes: {
subject: { model: 'subject' },
}
Subject.js
attributes: {
name: { type: 'string', unique: true, required: true },
}
当我为用户"/User "调用蓝图创建函数并传入数据时:
{
"name":"Test",
"subject":{"name":"Do Not Allow"}
}
它创建了用户,也创建了Subject。然而,我不想让主题被创建,我只希望能够附加一个现有的。例如,我希望它拒绝使用上述数据创建主题,但允许使用以下数据附加主题。
{
"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
可以看到,在验证和创建用户之前,它已经在验证和创建主题了
您希望在调用蓝图创建路由时避免创建关联对象。
创建一个策略(我将其命名为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',
}
};
您应该传递主题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
// }]
}
};
您可以为主题创建自定义类型,并在模型中添加您的逻辑。我不能100%确定我理解了附件有时部分,但也许这可以帮助:
模型/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。
如果我完全没有抓住重点…第二个选项是向模型中添加beforerecreate和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();
});
}
};
- 如何将getJson的响应保存在全局变量中
- 按下按钮时保存cookie
- 如何使用 Angular JS 将数据保存在数据库中
- 子字符串/正则表达式以获取字符串中保存的 SRC 值
- HTML5在画布中加载较小的图像并保存实际大小的图像
- 是否可以在浏览器中使用纯JavaScript保存音频流
- 如何将多个画布保存为一个图像
- 气质的“nestRemoting()”有时可以'找不到关系
- PHP:显示sqlite数据库中的html格式数据,使用tinymce保存
- 如何在Parse中创建一对多关系
- 如何将乳胶配方奶粉图像保存到Asp.net中的文件夹中
- Ext.js从json构建模型关系的问题
- 保存数组javascript
- 保存串行端口列表与流星
- 将JavaScript变量保存到Rails模型
- Ember.js将多对多关系保存到服务器
- 余烬.js有许多模型关系保存
- 在 Ember 中保存预订时更新具有关系的现有事件
- 如何在Ember.js中保存具有多对多关系的模型
- Waterline/SailsJs防止嵌套(关系)保存模型