Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize include array of nested object - node.js

I have relations:

(Track) -- M:1 --> (TrackChannel) <--1:M (Channel)
(User) -- M:1 --> (UserChannel) <--1:M (Channel)

  • Channel model include object Track as current_track_id with relation one to one.
  • Track and Channel is related many to many through TrackChannel
  • User and Channel is related many to many through UserChannel

/* Channel.js: */

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('channel', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    current_counter: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0
    },
    track_counter: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0
    },
    track_id: {
      type: DataTypes.STRING,
      allowNull: true,
      references: {
        model: 'track',
        key: 'id'
      }
    },
    createdAt: {
      type: DataTypes.TIME,
      allowNull: true,
      defaultValue: sequelize.fn('now')
    },
    updatedAt: {
      type: DataTypes.TIME,
      allowNull: true,
      defaultValue: sequelize.fn('now')
    }
  }, {
    tableName: 'channel',
    classMethods:{
      associate:function(models){
        this.belongsToMany(models.user, { onDelete: "CASCADE", foreignKey: 'user_id', otherKey: 'channel_id', through: 'userChannel' })
        this.belongsToMany(models.track, { onDelete: "CASCADE", foreignKey: 'track_id', otherKey: 'channel_id', through: 'trackChannel' })
        this.belongsTo(models.track, {foreignKey: 'current_track_id' , foreignKeyConstraint: true})
      }
    }
  });
};

What you are doing?

That is my query for the channel. I use repository pattern:

return db.channel.findOne({
            raw:true,
            include: [
                { model: db.track, attributes: ['id', 'name','artist_name' ,'album_name'], where: {track_id, }, paranoid: true, required: false}
            ],
            where: {
                id: id
            }
        });

What do you expect to happen?

I want to get:

{
  "id": "ce183d0a-e702-49a3-83b5-2912bbcf5283",
  "current_counter": 0,
  "track_counter": 0,
  "current_track_id": {} // object or null,
  "createdAt": "21:26:56.487217",
  "updatedAt": "21:26:56.487217",
  "tracks: [] // array or null
}

What is actually happening?

I try to create query to get one channel where is included current track object and list of track. Now it looks like that:

{
  "id": "ce183d0a-e702-49a3-83b5-2912bbcf5283",
  "current_counter": 0,
  "track_counter": 0,
  "track_id": null,
  "createdAt": "21:26:56.487217",
  "updatedAt": "21:26:56.487217",
  "tracks.id": null,
  "tracks.name": null,
  "tracks.artist_name": null,
  "tracks.album_name": null,
  "tracks.trackChannel.id": null,
  "tracks.trackChannel.channel_id": null,
  "tracks.trackChannel.createdAt": null,
  "tracks.trackChannel.updatedAt": null,
  "tracks.trackChannel.track_id": null
}

Dialect: postgres Database version: 9.6 Sequelize version: 3.3.0

like image 563
Michael Avatar asked Feb 04 '17 21:02

Michael


1 Answers

Guess it'll help someone so giving another option.

You can use nest:true along with raw:true property given by sequelize.

result:

before:

{
        id: 1,
        createdBy: 1,
        'Section.id': 1,
        'Section.name': 'Breakfast',
}

After:

{
  id: 1,
  createdBy: 1,
  Section: {
      id: 1,
      name: ''
      }
}
like image 188
SK16 Avatar answered Sep 21 '22 07:09

SK16