Добавить свойство в объект, возвращаемое Sequelize FindOne

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

router.get('/cats/1', function (req, res) {
    Cat.findOne({where: {id: 1}})
        .then(function (cat) {
            // cat exists and looks like {id: 1}
            cat.name = "Lincoln";
            // console.log of cat is {id: 1, name: Lincoln}
            res.json(cat);
        });
});

Клиент видит только {id: 1}, а не только добавленный ключ.

  • Что здесь происходит?
  • Какой тип объекта возвращается Sequelize?
  • Как добавить новые свойства кошкам и отправить их обратно?

Ответ 1

Класс Sequelize Model (из которых ваши кошки являются экземплярами) имеет метод toJSON(), который res.json предположительно будет использовать для сериализации ваших кошек. Метод возвращает результат Model#get() (https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L3613), который использует только атрибуты, определенные в модели. Если вы хотите установить имя кота, но не хранить имена в БД, вы можете использовать виртуальный столбец при определении своей модели cat:

sequelize.define('Cat', {
  // [other columns here...]
  name: Sequelize.VIRTUAL
});

В качестве альтернативы, если вы не хотите добавлять свойства к определению модели:

cat = cat.toJSON(); // actually returns a plain object, not a JSON string
cat.name = 'Macavity';
res.json(cat);

Ответ 2

Следующие работы для sequelize v4.

...
const order = Order.findOne(criteria);
order.setDataValue('additionalProperty', 'some value');
...

Надеюсь это поможет. Было немного поздно, но люди все еще ищут ответы.

Ответ 3

Это не позволит мне прокомментировать правильный ответ выше (fooobar.com/questions/1007988/...), просто хотел добавить вариант использования, где это помогло мне.

У меня есть база данных mysql, которую мы не можем изменить в схеме (должна работать со старой системой и новой системой, пока мы не сможем отказаться от старой системы), но мы добавили в MonogoDB и дополнительные функции, пока не сможем создать систему рефакторинг.

Вышеприведенный ответ о свойстве Virtual помог, потому что я в основном сделал бы заполнитель для информации mongo db (в данном случае - журнал активности объекта) и добавил ее при вызове службы findMyObject.

Например:

const model = sequelize.define('myobj', {
  id: {
    type: Sequelize.INTEGER,
    autoIncrement: true,
    primaryKey: true,
    field: 'eventId',
  },
  name: { type: Sequelize.STRING, allowNull: false },
  history: Sequelize.VIRTUAL,
  ...
}

Затем в MyObjectService вызов findMyObject:

...
const result = yield MyObject.findOne(query);
result.history = yield getMyObjectHistoryArray(id);
return result;

И результирующий JSON выглядит так:

{
  "id": 1,
  "name": "My Name",
  "history": [ 
    {...},
    {...},
  ]
}

Таким образом, мы смогли расширить объект без изменения базы данных, но в бэкэнде все еще есть объект, куда вы можете перейти:

let obj = yield findMyObject(id);
obj.name = "New Name";
return yield obj.save();  

Что вы не сможете сделать, если в функции findMyObject вы сделали {raw: true} или result.get({plain: true})

Ответ 4

Вы можете использовать toJSON(), чтобы преобразовать объект Sequelize в тип JSON, а затем добавить свойства, как мы делаем в js

Пример:

    UserModel.findById(req.params.id)
     .then(function (userIns) {

        // here userIns is Sequelize Object 
        // and data is Json Object

        let data = userIns.toJSON();
        data['displayName'] = 'John';

    })