将属性添加到Sequelize FindOne返回的对象

时间:2016-07-17 22:56:24

标签: javascript postgresql sequelize.js

我试图在将sequelize实例传递回客户端之前将其添加到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返回什么类型的对象?
  • 如何向我的猫添加新属性并将其发回?

5 个答案:

答案 0 :(得分:27)

Sequelize Model类(你的猫是实例)有一个toJSON()方法,res.json可能会用来序列化你的猫。该方法返回Model#get()https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L3613)的结果,该结果仅使用模型上定义的属性。如果您希望能够在数据库中设置猫名​​称而不是商店名称,则可以在定义猫模型时使用虚拟列:

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

答案 1 :(得分:6)

以下适用于续集v4。

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

希望这会有所帮助。有点晚了,但万一人们还在寻找答案。

答案 2 :(得分:1)

您可以使用 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';

    })

答案 3 :(得分:1)

对我有用的是使用setDataValue

router.get('/cats/1', function (req, res) {
    Cat.findOne({where: {id: 1}})
        .then(function (cat) {
            cat.setDataValue("name", "Lincoln");
            res.json(cat);
        });
});

该功能的规格

public setDataValue(key: string, value: any)

Update the underlying data value

Params:

Name    Type    Attribute   Description
key     string              key to set in instance data store   
value   any                 new value for given key

来源:https://sequelize.org/master/class/lib/model.js~Model.html#instance-method-setDataValue

答案 4 :(得分:0)

它不会让我对上面的正确答案(https://stackoverflow.com/a/38469390/562683)进行评论,只是想添加一个对我有帮助的用例。

我有一个现有的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})

,您将无法执行此操作