Sequelize cli creating association belongsto user or staff

1.9k views Asked by At

i found many things about associations but nothing to my particular case,
i created some models and i'm trying to associate them,
so i think it is a matter of understanding database modeling too.

I've got the models user and staff, both share an attribute user_id.

user.js

'use strict';
module.exports = function(sequelize, DataTypes) {
  var User = sequelize.define('User', {
    user_id: DataTypes.STRING,
    fullname: DataTypes.STRING,
    username: DataTypes.STRING,
    comment: DataTypes.TEXT
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here
        User.hasMany(models.Sshkey, {foreignKey: 'sshkey_id'})
      }
    }
  });
  return User;
};

staff.js

'use strict';
module.exports = function(sequelize, DataTypes) {
  var Staff = sequelize.define('Staff', {
    user_id: DataTypes.STRING,
    fullname: DataTypes.STRING,
    username: DataTypes.STRING,
    password: DataTypes.STRING,
    isAdmin: DataTypes.BOOLEAN
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here
        Staff.hasMany(models.Sshkey, {foreignKey: 'sshkey_id'})
      }
    }
  });
  return Staff;
};

And i've got a model sshkey which can belong to either an user or a staff member.
I'm using Sequelize cli and haven't done any migrations yet.
And i'm pretty new to Js and creating databases, thinking about the database models and the associations, and i'm curios if i could write or do such thing as:

'use strict';
module.exports = function(sequelize, DataTypes) {
  var Sshkey = sequelize.define('Sshkey', {
    sshkey_id: DataTypes.STRING,
    sshkey: DataTypes.TEXT
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here

        // My Problem starts here |
        // Should i write         |
        //                        |
        //                        V

        Sshkey.hasOne(models.User || models.Staff, {foreignKey: 'user_id'})

        // Or maybe:
        // Sshkey.hasOne(models.User, {foreignKey: 'user_id'}) ||
        // Sshkey.hasOne(models.Staff, {foreignKey: 'user_id'})
        // Should i rather rename models.Staffs foreignKey user_id to staff_id?

        // Or maybe:
        // Sshkey.hasOne(models.User, {as: 'userkey', foreignKey: 'user_id'})
        // Sshkey.hasOne(models.Staff, {as: 'staffkey', foreignKey: 'user_id'})

      }
    }
  });
  return Sshkey;
};

What would be a proper solution for the problem that if i later on want to reference a sshkey to either a user or a staff member?
Making two models with staffkeys and userkeys?
Thanks in advance,

BigZ

1

There are 1 answers

2
jjbskir On BEST ANSWER

If you want a 1:m relationship where the foreign key user_id is added to the Sshkey model, should be:

User.hasMany(models.Sshkey, {foreignKey: 'user_id'});
Staff.hasMany(models.Sshkey, {foreignKey: 'user_id'});
Sshkey.belongsTo(models.User, {foreignKey: 'user_id'});
Sshkey.belongsTo(models.Staff, {foreignKey: 'user_id'});

One issue I have with your example is that user_id and sshkey_id are both strings with no constraints around them, which makes them very bad foreignKey's and terrible for designing databases. To get a User and their Sshkey:

User.findAll({
  where: {},
  include: [ { model: Sshkey } ]
});