2013-08-05 2 views
4

Я создаю таблицу для хранения пользовательских сессий в я буду хранить IP-адрес в виде целого числа, используя эти методы:. IP-addresses stored as int results in overflow?Node.js Sequelize геттер/сеттер RangeError

Я хотел бы уточнить getter и setter для поля IP, чтобы он мог автоматически конвертировать между IP и int.

К сожалению, я получаю следующее сообщение об ошибке, и я понятия не имею, что происходит. Я пытался исправить это в течение нескольких часов, и Google не дает мне никаких результатов:

RangeError: Maximum call stack size exceeded

Модель:

model = db.define(name, { 
    id: {type: Sequelize.STRING, allowNull: false, primaryKey: true}, 
    ipAddress: {type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false}, 
    userAgent: {type: Sequelize.STRING, allowNull: false}, 
    username: {type: Sequelize.STRING, allowNull: false}, 
    password: {type: Sequelize.STRING, allowNull: false}, 
    firstName: {type: Sequelize.STRING, allowNull: false}, 
    lastName: {type: Sequelize.STRING, allowNull: false}, 
    email: {type: Sequelize.STRING} 
}, { 
    getterMethods: { 
     name: function() { return this.firstName + this.lastName }, 
     ipAddress: function() { 
      ip = this.getDataValue("ipAddress"); 
      return ((ip >> 24) & 255) + "." + ((ip >> 16) & 255) + "." + ((ip >> 8) & 255) + "." + (ip & 255); 
     } 
    }, 
    setterMethods: { 
     ipAddress: function(ip) { 
      var parts = ip.split("."); 
      var ret = 0; 
      ret += parseInt(parts[0], 10) << 24; 
      ret += parseInt(parts[1], 10) << 16; 
      ret += parseInt(parts[2], 10) << 8; 
      ret += parseInt(parts[3], 10); 
      return ret; 
     } 
    } 
}); 

вставив IP:

model.findOrCreate({id: sessionId}, { 
    id: sessionId, 
    ipAddress: req.ip, // === "192.168.1.79" 
    userAgent: req.get("user-agent"), 
    username: "test", 
    password: "test", 
    firstName: "first", 
    lastName: "last", 
    email: "email" 
}) 

Я могу подтвердить, что код getter/setter преобразуется по желанию, но он не работает в Sequelize правильно.

ответ

4

Я тоже столкнулся с этой проблемой с Sequelize. Я читал и перечитывал официальную документацию, искал везде, где я знал, чтобы искать в Интернете, и я, наконец, оказался здесь. Как только я нашел ваш вопрос, без ответов, я решил найти исходный код Sequelize. Конечно, я нашел ответ!

Если вы посмотрите на файл sequelize/test/dao-factory.test.js в исходном коде Sequelize, вы откроете для себя следующий фрагмент кода таится внутри теста:

setterMethods: { 
    price1: function(v) { this.setDataValue('price1', v * 100) } 
}, 

Я скопировал выше синтаксис, использовал его в своем собственном инкубаторе метод, и он работает!

Они действительно должны обновить документацию на веб-сайте sequelize .. Хм .. Возможно, мне стоит помочь им в этом? В любом случае, удачи вам!

1

Я не знаю, если кто-то все еще запускает эту ошибку, но если у вас возникли проблемы с этим, вот как я решил проблему.

У меня была похожая ситуация, когда у меня был объект UserModel, который был похож на это:

var UserModel = sequelize.define("users", { 
    ID: { 
     type: Sequelize.INTEGER, 
     field: "ID", 
     primaryKey: true, 
     autoIncrement: true 
    }, 
    Username: { 
     type: Sequelize.STRING, 
     field: "Username" 
    }, 
    Password: { 
     type: Sequelize.STRING, 
     field: "Password" 
    }, 
    Sector: { 
     type: Sequelize.INTEGER, 
     field: "Sector" 
    }, 
    SubSector: { 
     type: Sequelize.INTEGER, 
     field: "SubSector" 
    }, 
    Email: { 
     type: Sequelize.STRING, 
     field: "email" 
    }, 
    Status: { 
     type: Sequelize.INTEGER, 
     field: "status" 
    } 
} 

И мои сеттеров и добытчиками были:

{ 
    getterMethods: { 
     Sector: function() { 
      return this.Sector; 
     }, 
     Status: function() { 
      return this.Status; 
     } 
    }, 
    setterMethods: { 
     Sector: function(val) { 
      this.setDataValue('Sector',val); 
     }, 
     Status: function(val) { 
      this.setDataValue('Status',val); 
     } 
    } 
}); 

И, конечно, у меня была ошибка стека ,

Чтобы решить эту проблему, я только изменил мои сеттер и добытчик к этому:

{ 
    getterMethods: { 
     currSector: function() { 
      return this.Sector; 
     }, 
     currStatus: function() { 
      return this.Status; 
     } 
    }, 
    setterMethods: { 
     newSector: function(val) { 
      this.setDataValue('Sector',val); 
     }, 
     newStatus: function(val) { 
      this.setDataValue('Status',val); 
     } 
    } 
}); 

И все пошло волшебно хорошо, несмотря на множестве примеров онлайн Я видел человек, предполагающих подход обеспечения того же сеттеры/геттеры называют полями.

Итак, вкратце, изменив имя сеттеров и геттеров, чтобы их имя не соответствовало ни одному из определенных полей, которые разрешили мою проблему. Хорошая практика? Я не уверен, но это решило мою проблему.

1

У меня была похожая ситуация, и я решаю таким образом

const ProductImages = db.define('product_images', { 
    product_image_id: {type: Sequelize.INTEGER, primaryKey: true, 
    autoIncrement: true}, 
    url: Sequelize.TEXT, 
    product_id: Sequelize.INTEGER, 
    is_primary: Sequelize.INTEGER, 
}, { 
    timestamps: false, 

getterMethods: { 
    is_primary() { 
     return parseInt(this.dataValues.is_primary) 
    }, 

}, 
scopes: { 

    byDefault() { 
     return { 
      include: [{ 
       model: ProductDescriptions, as: 
        'product_description', where: {language_id: 1} 
      }] 
     }; 
     }, 

    } 

}) 

module.exports = ProductImages; 

Когда я называю this.davaValues.column_name не называть recoursive getterMethod для этого столбца

Смежные вопросы