Продолжить — включить возврат средства получения в обычный объект

#node.js #sequelize.js

#node.js #sequelize.js

Вопрос:

У меня есть класс Sequelize, определенный с несколькими виртуальными полями, определенными следующим образом:

 class Post extend Sequelize.Model {
  get age () {
    return duration(this.get('createdAt'), new Date()).days
  }
}
  

(Для краткости я пропустил фактические поля базы данных)

Я запускаю приложение Express, я хочу, чтобы эти виртуальные поля были отправлены клиенту. Когда я вызываю post.get({ plain: true }) , передаются только «реальные» поля базы данных. Я получаю что-то вроде этого:

 {"createdAt": "2019-03-05T09:16:50.391Z"}
  

Каков наилучший способ сделать ответ более похожим на этот вместо этого?:

 {"createdAt": "2019-03-07T09:16:50.391Z", "age": 3}
  

Ответ №1:

Есть ли причина для расширения модели? Использование свойства getterMethods, похоже, выполняет то, что вы просите. Например:

 sequelizeDB.define('my_printer_table',
  {
    printer_code    : {type: Sequelize.STRING,primaryKey: true},
    printer_name    : Sequelize.STRING
  },
  {
  getterMethods: {
    description() {
      return this.printer_code   ' '   this.printer_name
    }
  }
});
  

Затем printer.get() приводит к:

 Object {description: "ABC ABC Printing", printer_code: "ABC", printer_name: "ABC Printing"}
  

Комментарии:

1. Я расширил модель, потому что именно так написаны все модели в этом конкретном приложении (в этом стиле: codewithhugo.com/using-es6-classes-for-sequelize-4-models ). Это в проекте, который в значительной степени основан на объектах с большим количеством ES6, и согласованность была бы желательна.

Ответ №2:

Решение, к которому я в конечном итоге пришел, состояло в том, чтобы явно объявить getter в параметрах, аналогично предложению KenOn10, но в синтаксисе ES6. Вот готовое решение:

 class Post extend Sequelize.Model {

  static init (sequelize, DataTypes) {
    return super.init(
      'age': {
        type: DataTypes.VIRTUAL,
        get: function () { return this.getAge() }
      }
    }, { sequelize }
  }

  getAge () {
    return duration(this.get('createdAt'), new Date()).days
  }
}
  

Однако следует отметить пару моментов:

  • Я изменил функцию получения на обычную вызываемую функцию getAge() , потому что установка get свойства в схеме также создает его как средство получения. Следовательно, если вы вызываете средство получения внутри этой функции, оно переходит в рекурсивный цикл и заполняет стек.
  • get Параметр должен быть определен как полноценная функция, поскольку функции со стрелками не имеют своего собственного this контекста.