В парусах использовать «базовую модель», наследовать от этого и использовать функции базового класса? - PullRequest
0 голосов
/ 01 октября 2018

Чтобы улучшить нашу программу и уменьшить избыточность кода, мы хотим создать некоторое наследование внутри моделей.

Теперь возьмем типичную модель User, в которой поле имени и пароля имеет значение «базовый класс» инесколько подклассов могут улучшить это в зависимости от потребностей конкретного приложения.

Таким образом, baseuser будет выглядеть так:

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();
  },
}

Этот пустой класс не соответствует какой-либо отдельной таблице базы данных.Теперь в производном от этого классе, VerifyableUser (модель для пользователей, которые должны иметь ссылки для проверки), есть несколько дополнительных полей, одно из которых является URL-адресом для проверки.

Теперь для "расширения" классов lodash '_.merge используется функция, как объяснено в этом вопросе .

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();
  }
};

Теперь проблема должна быть очевидной, производный класс 'beforeCreate перезаписывает исходный beforeCreate: вВ обычной ОО-среде это тоже не большая проблема, так как я мог бы просто позвонить Base.beforeCreate() или что-то подобное.Однако можно ли что-то сделать с помощью lodash 'merge?Или я должен использовать другой способ для расширения объектов?(Или я действительно должен повторить себя и набрать beforeCreate?).

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Вы также можете использовать _. MergeWith , чтобы проверить, что представляет собой каждое объединяемое свойство и является ли оно функцией, просто выберите объект, а не источник (в вашем случае source is 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>
0 голосов
/ 01 октября 2018

или что-то подобное:

 // VerifyableUser
 async beforeCreate(user, cb) {
  await BaseUser.beforeCreate(user, () => 0);
  //...
 }
...