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:

  1. Project.hasMany(Task)
  2. Task.belongsTo(Project)
  3. Project.create()...
  4. Task.create()...
  5. Task.create()...
  6. // save them... and then:
  7. project.setTasks([task1, task2]).then(() => {
  8. // saved!
  9. })
  10. // ok, now they are saved... how do I get them later on?
  11. project.getTasks().then(associatedTasks => {
  12. // associatedTasks is an array of tasks
  13. })
  14. // You can also pass filters to the getter method.
  15. // They are equal to the options you can pass to a usual finder method.
  16. project.getTasks({ where: 'id > 10' }).then(tasks => {
  17. // tasks with an id greater than 10 :)
  18. })
  19. // You can also only retrieve certain fields of a associated object.
  20. project.getTasks({attributes: ['title']}).then(tasks => {
  21. // retrieve tasks with the attributes "title" and "id"
  22. })

To remove created associations you can just call the set method without a specific id:

  1. // remove the association with task1
  2. project.setTasks([task2]).then(associatedTasks => {
  3. // you will get task2 only
  4. })
  5. // remove 'em all
  6. project.setTasks([]).then(associatedTasks => {
  7. // you will get an empty array
  8. })
  9. // or remove 'em more directly
  10. project.removeTask(task1).then(() => {
  11. // it's gone
  12. })
  13. // and add 'em again
  14. project.addTask(task1).then(() => {
  15. // it's back again
  16. })

You can of course also do it vice versa:

  1. // project is associated with task1 and task2
  2. task2.setProject(null).then(() => {
  3. // and it's gone
  4. })

For hasOne/belongsTo it's basically the same:

  1. Task.hasOne(User, {as: "Author"})
  2. 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):

  1. // Either by adding a property with the name of the join table model to the object, before creating the association
  2. project.UserProjects = {
  3. status: 'active'
  4. }
  5. u.addProject(project)
  6. // Or by providing a second options.through argument when adding the association, containing the data that should go in the join table
  7. u.addProject(project, { through: { status: 'active' }})
  8. // When associating multiple objects, you can combine the two options above. In this case the second argument
  9. // will be treated as a defaults object, that will be used if no data is provided
  10. project1.UserProjects = {
  11. status: 'inactive'
  12. }
  13. u.setProjects([project1, project2], { through: { status: 'active' }})
  14. // 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:

  1. u.getProjects().then(projects => {
  2. const project = projects[0]
  3. if (project.UserProjects.status === 'active') {
  4. // .. do magic
  5. // since this is a real DAO instance, you can save it directly after you are done doing magic
  6. return project.UserProjects.save()
  7. }
  8. })

If you only need some of the attributes from the join table, you can provide an array with the attributes you want:

  1. // This will select only name from the Projects table, and only status from the UserProjects table
  2. user.getProjects({ attributes: ['name'], joinTableAttributes: ['status']})