web-dev-qa-db-ja.com

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が返すオブジェクトの種類は何ですか?
  • 猫に新しいプロパティを追加して送り返すにはどうすればよいですか?
19
Rastalamm

Sequelize Modelクラス(猫はインスタンスです)にはtoJSON()メソッドがあり、res.jsonはおそらく猫をシリアル化するために使用します。このメソッドは、Model#get()https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L361 )の結果を返します。モデルで定義された属性を使用します。猫の名前を設定できるようにしたいが、DBに名前を保存したくない場合は、猫のモデルを定義するときに仮想列を使用できます。

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

以下は、sequelize v4で機能します。

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

お役に立てれば。少し遅いですが、人々がまだ答えを探している場合に備えて。

11
Eric Xin Zhang

上記の正解( https://stackoverflow.com/a/38469390/56268 )についてコメントすることはできません。これが私に役立つユースケースを追加したかっただけです。

スキーマを変更できない既存のmysqlデータベースがあります(古いシステムを廃止するまでは古いシステムと新しいシステムで動作する必要があります)。リファクタリング。

私は基本的にmongo db情報(この場合はオブジェクトアクティビティログ)のプレースホルダーを作成して 'findMyObject'サービス呼び出しに追加するため、上記のVirtualプロパティの答えが役立ちました。

例えば:

_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": [ 
    {...},
    {...},
  ]
}
_

したがって、dbを変更せずにオブジェクトを拡張することができましたが、バックエンドに移動可能なオブジェクトがあります。

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

FindMyObject関数で_{raw: true}_またはresult.get({plain: true})のいずれかを実行した場合、これは実行できません。

1
James Cori

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

    })
1
Om Sharma

私にとってうまくいくのは、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

0
7hibault