1

次の Bookshelf モデルは、モデルの保存時にユーザーのパスワードをハッシュします。唯一の問題は、そのmodel.set()呼び出しを aに変更するとmodel.save()、無限の保存/変更ループに入るということです。

var User = bookshelf.Model.extend({
    tableName: 'users',
    hasTimestamps: true,

    constructor: function() {
        var self = this;
        bookshelf.Model.apply(this, arguments);

        this.on('saving', function(model) {
            if(!model.get('password')) {
                return self.hashPassword(model);
            }
        });
    },

    hashPassword: function(model) {
        bcrypt.genSalt(10, function(error, salt) {
            bcrypt.hash(model.attributes.password, salt, function(error, hash) {
                model.set({password: hash});
                console.log(model.attributes);
            });
        });
    }
});

バックボーンには、変更されたイベントをトリガーしないsilent: trueように渡すことができるオプションがあることは知っていますが、ブックシェルフはそれをサポートしていないと思います。save()

model.set()保存/変更ループを発生させることなく、行った変更を保存するにはどうすればよいですか?

4

1 に答える 1

3

したがって、hash_password メソッドが値を返す前にモデルが保存されていることが判明したため、bcrypt コードを次のように約束しました。

hashPassword: function(password) {
    return new Promise(function(resolve, reject) {
        bcrypt.genSalt(10, function(error, salt) {
            if(error) return reject(error);

            bcrypt.hash(password, salt, function(error, hash) {
                if(error) return reject(error);
                return resolve(hash);
            });
        });
    });
}

モデルのコンストラクターを完全にリファクタリングして、それを使用します。

constructor: function() {
    var self = this;
    bookshelf.Model.apply(this, arguments);

    this.on('saving', function(model) {
        if(!model.attributes.password) {
            delete model.attributes.password;
        } else {
            return self.hashPassword(model.attributes.password)
            .then(function(hash) {
                model.set({ password: hash });
            });
        }
    });
}

これが誰かに役立つことを願っています:-)

于 2015-05-06T21:43:35.350 に答える