Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize associations hasOne, belongsTo

The problem is that I can not get working the relation hasOne, which does not eager load the state type object.

All the queries are done on existing tables.

Here is the customer table, whats important is the cst_state_type field:

module.exports = function(sequelize, DataTypes) {

    return sequelize.define('customer', {

        customer: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true,
            allowNull: true,
            validate: {
                isNumeric: true
            }
        },
        first_name: {
            type: DataTypes.STRING(100),
            validate: {
                isAlphanumeric: true
            }
        },
        last_name: DataTypes.STRING(100),
        identity_code: {
            type: DataTypes.STRING(20),
            allowNull: true,
            validate: {
                isNumeric: true
            }
        },
        note: DataTypes.STRING(1000),
        birth_date: DataTypes.DATE,


        created_by: DataTypes.INTEGER,
        updated_by: DataTypes.INTEGER,

        cst_type: DataTypes.INTEGER,
        cst_state_type:  {
            type: DataTypes.INTEGER,
        }

    }, {
        tableName: 'customer',

        updatedAt: 'updated',
        createdAt: 'created',
        timestamps: true
    });
};

cst_state_type table:

module.exports = function(sequelize, DataTypes) {

    return sequelize.define('StateType', {

        cst_state_type: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true,
            validate: {
            }
        },
        name: DataTypes.STRING(100),
    }, {
        tableName: 'cst_state_type',
        timestamps: false
    });
};

How the relations are described:

  global.db.Customer.hasOne(global.db.StateType, {
    foreignKey: 'cst_state_type',
    as: 'state_type'
  });

  global.db.StateType.belongsTo(global.db.Customer, {
    foreignKey: 'cst_state_type'
  });

And creating eager loading query:

    db.Customer.findAll( {
        include: [
            { model: db.Address, as: 'addresses' },
            { model: db.StateType, as: 'state_type' }
        ]
    })
        .success(function (customers) {
            res.json(200, customers);
        })
        .fail(function (error) {
            res.json(500, { msg: error });
        });
like image 598
Risto Novik Avatar asked Sep 29 '13 08:09

Risto Novik


People also ask

What is hasOne Association in Sequelize?

The Sequelize hasOne() association method is used to establish an association between two defined Sequelize models. The association method allows you to link two models so that you can retrieve data from both tables with one query execution.

How do you use belongsTo in Sequelize?

You can make the Task model belongs to the User model by calling the belongsTo() method from the Task model like this: Task. belongsTo(User); The belongsTo() method above will associate the Task model with the User model, adding the UserId attribute to the Task model as the foreign key constraint.

How do you do associations in Sequelize?

Creating associations in sequelize is done by calling one of the belongsTo / hasOne / hasMany / belongsToMany functions on a model (the source), and providing another model as the first argument to the function (the target). hasOne - adds a foreign key to the target and singular association mixins to the source.

How do you create a one to many relationship in Sequelize?

To create a One-To-One relationship, the hasOne and belongsTo associations are used together; To create a One-To-Many relationship, the hasMany and belongsTo associations are used together; To create a Many-To-Many relationship, two belongsToMany calls are used together.


2 Answers

Thanks for you answer, it helped me a lot. You can also add the relations directly in your model by using classmethods. I added a example below, hope this helps!

User Model (file)

module.exports = function(sequelize, DataTypes){
    var User = sequelize.define(
        'User', {
            name: {
                type: DataTypes.STRING,
                allowNull: false
            }
        },
        {
            classMethods:{
                associate:function(models){
                    User.hasMany(models.Comment, { foreignKey: 'userId'} );
                }
            }
        }

    );
    return User;
};

Comment Model (file):

module.exports = function(sequelize, DataTypes){
    var Comment = sequelize.define(
        'Comment', {
            text: {
                type: DataTypes.STRING,
                allowNull: false
            }
        },
        {
            classMethods:{
                associate:function(models){
                    Comment.belongsTo(models.User, { foreignKey:'userId'} );
                }
            }
        }

    );
    return Comment;
};

You don't have to set the foreignkey, sequelize will handle it if you don't specify the foreignkeys.

Then in the query:

models.Comment.find({
        where: { id: id },
        include: [
            models.User
        ],
        limit: 1
    })
like image 109
Gerard Avatar answered Oct 23 '22 18:10

Gerard


I'm pretty sure that the error is in your associations somewhere. From the way you described your table structure, the assocations should look something like this:

global.db.Customer.belongsTo(global.db.StateType, {
    foreignKey: 'cst_state_type',
    as: 'state_type'
});

global.db.StateType.hasMany(global.db.Customer, {
    foreignKey: 'cst_state_type'
});

As i understand it, the same state can be assigned to many customers, therefore StateType.hasMany. The relation from customer -> statetype is a "back-assocation", meaning that the foreign key is in the customer table. For that you need belongsTo

like image 38
Jan Aagaard Meier Avatar answered Oct 23 '22 18:10

Jan Aagaard Meier