6

モデルで一意のフィールドを定義しましたが、テストしようとすると、Error (E_UNKNOWN) :: Encountered an unexpected error: MongoError: E11000 duplicate key error index:代わりに帆の ValidationError が発生するため、帆によってチェックされていないようです。

帆のユニークなフィールドを処理する最良の方法は何ですか?

// model/User.js
module.exports{
attributes: {
  email: {required: true, unique: true, type: 'email' },
  ....
}
// in my controller
User.create({email: 'hello@gmail.com'}).then(...).fail(....)
User.create({email: 'hello@gmail.com'}).then(...).fail(// throws the mongo error ) 
// and same goes with update it throws error

よろしくお願いします。

4

6 に答える 6

10

このunique属性は現在、MongoDB で一意のインデックスのみを作成します

コールバックを使用してbeforeValidate()、その属性を持つ既存のレコードをチェックし、結果をクラス変数に保存できます。

このアプローチにより、モデルが適切な検証エラーを返し、クライアントが評価できるようになります。

var uniqueEmail = false;

module.exports = {


    /**
     * Custom validation types
     */
    types: {
        uniqueEmail: function(value) {
            return uniqueEmail;
        }
    },

    /**
     * Model attributes
     */
    attributes: {
        email: {
            type: 'email',
            required: true,
            unique: true,            // Creates a unique index in MongoDB
            uniqueEmail: true        // Makes sure there is no existing record with this email in MongoDB
        }
    },

    /**
     * Lifecycle Callbacks
     */
    beforeValidate: function(values, cb) {
        User.findOne({email: values.email}).exec(function (err, record) {
            uniqueEmail = !err && !record;
            cb();
        });
    }
}

編集

thinktt が指摘したように、以前のソリューションにはエラーがあり、デフォルトuniqueEmail値はモデル宣言自体内で定義されているため、モデル コード内で参照できないため、役に立たなくなりました。それに応じて回答を編集しました、ありがとう。

于 2015-03-13T12:09:17.437 に答える
0

これを行う正しい方法!!!

module.exports = {
schema: true,
migrate: 'safe',
tableName: 'users',
autoCreatedAt: false,
autoUpdatedAt: false,
adapter: 'mysql',

/**
 * Custom validation types
 */
types: {
    uniquePhone: function(value) {
        return value!=='_unique';
    }
},
attributes: {
    id: {
        type: 'integer',
        primaryKey: true,
        unique: true,
        autoIncrement: true
    },
    email: {
        type: 'email'
    },
    first_name: {
        type: 'string'
    },
    last_name: {
        type: 'string'
    },
    phone: {
        type: 'string',
        required: true,
        uniquePhone: true
    }

},
/**
 * Lifecycle Callbacks
 */
beforeValidate: function(values, cb) {
    Users.findOne({phone: values.phone}).exec(function(err, record) {
        // do whatever you want check against various scenarios
        // and so on.. 
        if(record){
            values.phone='_unique';
        }
        cb();
    });
}

};

このようにして、バリデーターの概念を壊していません!

于 2016-05-14T08:21:37.273 に答える
0

Sails v1.2.7 の最新バージョンでは、コールバックが機能しなくなりました。モデルで一意性が機能しないという問題が発生した場合 (sails-mongo で行ったように)、コントローラーで手動で構成する必要があります。

これが例です

//SIGNUP
create: async (req, res) => {
    const { name, email, password } = req.body;
    try {
      const userExists = await sails.models.user.findOne({ email });
      if (userExists) {
        throw 'That email address is already in use.';
      }
}
于 2020-07-23T12:50:19.577 に答える