Search code examples
node.jssequelize.jsmodelsinstance-methods

Sequelize: 'findAll' in instance method getParticipants()?


Specification for my conference instance method:

getParticipants() : Promise -> Participant array

Conference model:

return sequelize.define('conference', {

    id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true
    },

    name: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true
    },

    maxParticipants: {
        type: Sequelize.INTEGER,
        allowNull: false
    },

    fileShareSession: {
        type: Sequelize.STRING,
        defaultValue: null,
        allowNull: true
    },

    startDate: {
        type: Sequelize.DATE,
        defaultValue: null,
        allowNull: true
    },

    endDate: {
        type: Sequelize.DATE,
        defaultValue: null,
        allowNull: true
    },

    state: {
        type: Sequelize.ENUM(
            ConferenceState.new,
            ConferenceState.starting,
            ..
        ),
        defaultValue: ConferenceState.new,
        required: true,
        allowNull: false
    }

Participant model:

return sequelize.define('participant', {

    id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true
    },

    displayName: {
        type: Sequelize.STRING,
        defaultValue: null,
        allowNull: true
    },

    mediaResourceId: {
        type: Sequelize.STRING,
        defaultValue: null,
        allowNull: true
    },

    screenSharingId: {
        type: Sequelize.STRING,
        defaultValue: null,
        allowNull: true
    },

    mediaType: {
        type: Sequelize.ENUM(
            MediaType.AUDIO_VIDEO),
        defaultValue: MediaType.AUDIO_VIDEO,
        allowNull: false
    },

    state: {
        type: Sequelize.ENUM(
            ParticipantState.new,
            ParticipantState.joining,
            ..
        ),
        defaultValue: ParticipantState.new,
        required: true,
        allowNull: false
    }

Question:

So can I do a participant.findAll in my conferencing instance model or not? When yes, do I get an Array back with a findAll?

I would have done it like that:

// getParticipants() : Promise -> Participant array
      getParticipants() {
          return new Promise((resolve, reject) => {
              var Participant = sequelize.models.participant;
              Participant.findAll({
                  where: {
                      id: id
                  }
              }).then(function(participant) {
                  if (_.isObject(participant)) {
                      resolve(participant);
                  } else {
                      throw new ResourceNotFound(conference.name, {id: id});
                  }
              }).catch(function(err) {
                  reject(err);
              });
          });
      },

Solution

  • LAZY loading is implemented by sequelize when you make relationships between tables. You could make a relationship as follows:

    var Conference = sequelize.define('conference', { ... });
    
    var Participant = sequelize.define('participant', { ... });
    
    Conference.belongsToMany(Participant, { through: 'ConferenceParticipants'});
    
    Participant.belongsToMany(Conference, { through: 'ConferenceParticipants'});
    

    Then you can implement EAGER loading when you query your database like:

    // Obtain the participant list included in the original object (EAGER)
    var conference = 
     Conference.findOne({ 
        attributes: ['field1', 'field2', ...],
        where: {title: 'Conference A'},
        includes: [{
          attributes: ['field1', 'field2', ...],
          model: Participant,
          through: { model: 'ConferenceParticipants'} // You have to name the join table
        }]
      })
      .then(function(conference) {
          // Here you will have the conference with the list of participants
    
      });
    

    If you want to use LAZY loading, sequelize implement it for you, you just need to call below methods:

    // Obtain the participant LAZY
    conference.getParticipants().then(function(participants) {
      // participants is an array of participant
    })
    
    // You can also pass filters to the getter method.
    // They are equal to the options you can pass to a usual finder method.
    conference.getParticipants({ where: 'id > 10' }).then(function(participants) {
      // participants with an id greater than 10 :)
    })
    
    // You can also only retrieve certain fields of a associated object.
    conference.getParticipants({attributes: ['title']}).then(function(participants) {
        // retrieve participants with the attributes "title" and "id"
    })
    

    You can get a reference to sequelize relationship implementation in next document.