Zerzio
Zerzio

Reputation: 249

Sequelize associations with foreign keys

I'm really missing this in Sequelize. The .hasMany definition works with a mapping on the ID only. Let's take the usual project/tasks simple example. Let says then that a project has a VERSION attribute and should be associated with tasks having the same VERSION attribute.

I need a way to force the relation to be based on two attributes: the ID and the VERSION.

I strongly believe we need a way to make associations based on multiple foreign keys (called composite keys)

In my project I had to add a bunch of methods to the models to provide substitute to the getTasks using multiple keys.

If someone has a suggestion he's welcome.

Upvotes: 4

Views: 6047

Answers (1)

Jan Aagaard Meier
Jan Aagaard Meier

Reputation: 28788

This is also something we needed in our project. We have added the functionality that we needed, and are using it daily in our project, but the functionality is not fully tested, so we have not yet submitted a pull request.

You can however find the code at https://github.com/innofluence/sequelize/tree/newedge

specs/associations/composite-key.spec.js shows the API:

Article = sequelize.define('Article', {
  'title': Sequelize.STRING
}, {
  instanceMethods: {
    item_key: 'article'
  }        
});

Label = sequelize.define('Label', {
  'text': Sequelize.STRING
})

Label.hasMany(Article, {foreignKey: "label_id", joinTableName: "item_label" });
Article.hasMany(Label, {foreignKey:{ "item_id": "id", "item": "item_key" }, joinTableName: "item_label" });

In this example an article can have multiple labels. The join table (item_label) has the following rows: id, item, item_id, label_id. The important thing here is the last line, which shows that the link between Label and Article is a composite key. The foreign key is given as a map in which keys are the rows in the join table, and values are the values from an article row. You can see here that item in the item_label maps to item_key, which is an instance method on article. This is because all articles have the key article, so there is no need to save that in the db.

I hope this has been helpful, and if you are still in doubt, please feel free to post your sequelize model code and I will try to help :-)

Upvotes: 4

Related Questions