Associating objects
Because Sequelize is doing a lot of magic, you have to call Sequelize.sync
after setting the associations! Doing so will allow you the following:
Project.hasMany(Task)
Task.belongsTo(Project)
Project.create()...
Task.create()...
Task.create()...
// save them... and then:
project.setTasks([task1, task2]).then(() => {
// saved!
})
// ok, now they are saved... how do I get them later on?
project.getTasks().then(associatedTasks => {
// associatedTasks is an array of tasks
})
// You can also pass filters to the getter method.
// They are equal to the options you can pass to a usual finder method.
project.getTasks({ where: 'id > 10' }).then(tasks => {
// tasks with an id greater than 10 :)
})
// You can also only retrieve certain fields of a associated object.
project.getTasks({attributes: ['title']}).then(tasks => {
// retrieve tasks with the attributes "title" and "id"
})
To remove created associations you can just call the set method without a specific id:
// remove the association with task1
project.setTasks([task2]).then(associatedTasks => {
// you will get task2 only
})
// remove 'em all
project.setTasks([]).then(associatedTasks => {
// you will get an empty array
})
// or remove 'em more directly
project.removeTask(task1).then(() => {
// it's gone
})
// and add 'em again
project.addTask(task1).then(() => {
// it's back again
})
You can of course also do it vice versa:
// project is associated with task1 and task2
task2.setProject(null).then(() => {
// and it's gone
})
For hasOne/belongsTo it's basically the same:
Task.hasOne(User, {as: "Author"})
Task.setAuthor(anAuthor)
Adding associations to a relation with a custom join table can be done in two ways (continuing with the associations defined in the previous chapter):
// Either by adding a property with the name of the join table model to the object, before creating the association
project.UserProjects = {
status: 'active'
}
u.addProject(project)
// Or by providing a second options.through argument when adding the association, containing the data that should go in the join table
u.addProject(project, { through: { status: 'active' }})
// When associating multiple objects, you can combine the two options above. In this case the second argument
// will be treated as a defaults object, that will be used if no data is provided
project1.UserProjects = {
status: 'inactive'
}
u.setProjects([project1, project2], { through: { status: 'active' }})
// The code above will record inactive for project one, and active for project two in the join table
When getting data on an association that has a custom join table, the data from the join table will be returned as a DAO instance:
u.getProjects().then(projects => {
const project = projects[0]
if (project.UserProjects.status === 'active') {
// .. do magic
// since this is a real DAO instance, you can save it directly after you are done doing magic
return project.UserProjects.save()
}
})
If you only need some of the attributes from the join table, you can provide an array with the attributes you want:
// This will select only name from the Projects table, and only status from the UserProjects table
user.getProjects({ attributes: ['name'], joinTableAttributes: ['status']})