Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize 'hasMany' associated(model) count in attributes in query execution

Sequelize version: 4.22.6, MySql version:5.7.8 I want to 'hasMany' associated(CompanyUser) count in attibutes(at place of _user_count_) in query execution

/**
* Company user associate with Company with belongsTo relation
*/
`CompanyUser.belongsTo(Company, { foreignKey: 'company_id', targetKey: 'id'});`

/**
* Company  associate with Company user with hasMany relation
*/
`Company.hasMany(CompanyUser, { foreignKey: 'company_id', sourceKey: 'id'});`

`return Company.findAll({
    attributes: [
        'id', 'title', 'is_enabled', '_user_count_'
    ]
    include: [
        {
            model: sqConn.CompanyUser,
            attributes: ['id'],
        },
        {
            model: sqConn.CompanyLogo,
            attributes:['file_object'],
        }
    ],
}).then(function(model) {
    return sequelize.Promise.resolve(model);
}).catch(function(err) {
    return sequelize.Promise.reject(err);
});`

Simple MySQL query with left-join works fine and give count.

like image 338
Ansari Maksud Avatar asked Sep 25 '18 11:09

Ansari Maksud


People also ask

What is Sequelize FN?

Function fnCreates a object representing a database function. This can be used in search queries, both in where and order parts, and as default values in column definitions. If you want to refer to columns in your function, you should use sequelize.


2 Answers

You can use sequelize.fn , try to run below query :

Company.findAll({
    attributes: [
        'id', 'title', 'is_enabled',
        [sequelize.fn('count', sequelize.col('company_users.id')) ,'user_count'] // <---- Here you will get the total count of user
    ],
    include: [
        {
            model: sqConn.CompanyUser,
            attributes: [] // <----- Make sure , this should be empty
        }
    ],
    group: ['companies.id'] // <---- You might require this one also
}).then(data => { 
    console.log(data); // <---- Check the output
})
like image 89
Vivek Doshi Avatar answered Nov 08 '22 12:11

Vivek Doshi


this is something that works for me:

await PostModel.findAll({
  group: ['posts.id'],
  order: [['createdAt', 'DESC']],
  include: [
    {
      model: CategoryModel,
      attributes: ['title'],
      where: { title: categoryTitle }
    },
    { model: CommentModel },
    { model: UserModel, attributes: ['fullname', 'id'] }
  ],
  attributes: [
    'title', 'content', 'description', 'thumbnail', 'baner', 'createdAt', 'updatedAt',
    [Sequelize.fn('COUNT', 'comment.id'), 'commentsCounter']
  ]
});

Associations:

  • Post M:N Category
  • Post 1:N Comment
  • Post N:1 User

please note to this part 'comment.id' not 'comments.id'.

if you use 'comments.id' it throws this error for you: SequelizeDatabaseError: missing FROM-clause entry for table "comments"

MY MODELS - UPDATE: post, category, and user model and comment

const { sequelize } = require('./index');
const { Model, DataTypes } = require('sequelize');
class CommentModel extends Model {};
CommentModel.init({
    id: {
        primaryKey: true,
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4
    },
    content: {
        type: DataTypes.TEXT,
        allowNull: false
    }
}, {
    sequelize,
    modelName: 'comments',
    timestamps: true,
    paranoid: false
});

module.exports = CommentModel;
like image 42
Kasir Barati Avatar answered Nov 08 '22 10:11

Kasir Barati