在 sails 中使用 "basemodel",从中派生并使用基类函数?
In sails use a "basemodel", derive from that and use baseclass functions?
为了改进我们的程序并减少代码冗余,我们希望在模型内部创建一些继承..
现在采用一个典型的 User
模型,它有一个名称和密码字段 "baseclass" 并且几个子 class 可以根据特定应用程序的需要对此进行改进。
所以基本用户看起来像:
module.exports = {
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
password: {
type: 'string',
required: true,
},
},
beforeCreate: async function(user, cb) {
const hash = await bcrypt.hash(user.password, 10);
user.password = hash;
cb();
},
}
这个空 class 本身不对应任何数据库 table。现在在派生class中,VerifyableUser
(必须有验证链接的用户模型),有一些额外的字段,一个是验证url.
现在 "extend" classes lodash' _.merge
函数被使用,如 this question 中所述。
const BaseUser = require("../../BaseUser.js");
module.exports = _.merge({}, BaseUser, {
attributes: {
verify_key: {
type: 'string'
}
},
beforeCreate: async function(user, cb) {
user.verify_key = 'helloworld'; //crypto used to generate...
cb();
}
};
现在问题应该很明显了,派生的class'beforeCreate
覆盖了原来的beforeCreate
:在正常的OO环境中这也不是什么大问题,因为我可以只调用 Base.beforeCreate()
或类似的东西。
然而,可以使用 lodash 的合并来完成某些事情吗?或者我应该使用另一种方式来扩展对象? (或者我真的必须重复自己并重新输入 beforeCreate
吗?)。
或类似的东西:
// VerifyableUser
async beforeCreate(user, cb) {
await BaseUser.beforeCreate(user, () => 0);
//...
}
您还可以使用 _.mergeWith 来检查每个 属性 被合并的是什么,如果它是一个函数,只需选择对象而不是源(在你的例子中 source
是 BaseUser
):
const BaseUser = require("../../BaseUser.js");
let obj = {
attributes: {
verify_key: {
type: 'string'
}
},
beforeCreate: async function(user, cb) {
user.verify_key = 'helloworld'; //crypto used to generate...
cb();
}
}
module.exports = _.mergeWith(
obj,
BaseUser,
(objValue, srcValue, key, object, source) => _.isFunction(objValue) ? objValue : _.merge(object[key], source[key])
)
这是一个测试:
var data = {
food: "chicken",
foo: () => console.log('chicken!')
}
var source = {
prop1: 1,
prop2: 1,
foo: () => console.log('foo!')
}
var result = _.merge(data, source, (objValue, srcValue, key, object, source) => _.isFunction(objValue) ? objValue : _.merge(object[key], source[key]))
console.log(result)
result.foo()
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
为了改进我们的程序并减少代码冗余,我们希望在模型内部创建一些继承..
现在采用一个典型的 User
模型,它有一个名称和密码字段 "baseclass" 并且几个子 class 可以根据特定应用程序的需要对此进行改进。
所以基本用户看起来像:
module.exports = {
attributes: {
username: {
type: 'string',
required: true,
unique: true
},
password: {
type: 'string',
required: true,
},
},
beforeCreate: async function(user, cb) {
const hash = await bcrypt.hash(user.password, 10);
user.password = hash;
cb();
},
}
这个空 class 本身不对应任何数据库 table。现在在派生class中,VerifyableUser
(必须有验证链接的用户模型),有一些额外的字段,一个是验证url.
现在 "extend" classes lodash' _.merge
函数被使用,如 this question 中所述。
const BaseUser = require("../../BaseUser.js");
module.exports = _.merge({}, BaseUser, {
attributes: {
verify_key: {
type: 'string'
}
},
beforeCreate: async function(user, cb) {
user.verify_key = 'helloworld'; //crypto used to generate...
cb();
}
};
现在问题应该很明显了,派生的class'beforeCreate
覆盖了原来的beforeCreate
:在正常的OO环境中这也不是什么大问题,因为我可以只调用 Base.beforeCreate()
或类似的东西。
然而,可以使用 lodash 的合并来完成某些事情吗?或者我应该使用另一种方式来扩展对象? (或者我真的必须重复自己并重新输入 beforeCreate
吗?)。
或类似的东西:
// VerifyableUser
async beforeCreate(user, cb) {
await BaseUser.beforeCreate(user, () => 0);
//...
}
您还可以使用 _.mergeWith 来检查每个 属性 被合并的是什么,如果它是一个函数,只需选择对象而不是源(在你的例子中 source
是 BaseUser
):
const BaseUser = require("../../BaseUser.js");
let obj = {
attributes: {
verify_key: {
type: 'string'
}
},
beforeCreate: async function(user, cb) {
user.verify_key = 'helloworld'; //crypto used to generate...
cb();
}
}
module.exports = _.mergeWith(
obj,
BaseUser,
(objValue, srcValue, key, object, source) => _.isFunction(objValue) ? objValue : _.merge(object[key], source[key])
)
这是一个测试:
var data = {
food: "chicken",
foo: () => console.log('chicken!')
}
var source = {
prop1: 1,
prop2: 1,
foo: () => console.log('foo!')
}
var result = _.merge(data, source, (objValue, srcValue, key, object, source) => _.isFunction(objValue) ? objValue : _.merge(object[key], source[key]))
console.log(result)
result.foo()
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>