在 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 来检查每个 属性 被合并的是什么,如果它是一个函数,只需选择对象而不是源(在你的例子中 sourceBaseUser):

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>