How to do a LEFT JOIN in Sequelize with more than one predicate in the ON clause?

12,704

Excuse the lack of CoffeeScript, but you could do something like:

Post.findAll({
    include: [{
        model: PostLike,
        where: { author_id: 123 }
    }]
})

I've found the following comments in the code which may also be of use.

* @param  {Array<Object|Model>}       [options.include] A list of associations to eagerly load using a left join. Supported is either `{ include: [ Model1, Model2, ...]}` or `{ include: [{ model: Model1, as: 'Alias' }]}`. If your association are set up with an `as` (eg. `X.hasMany(Y, { as: 'Z }`, you need to specify Z in the as attribute when eager loading Y).
   * @param  {Model}                     [options.include[].model] The model you want to eagerly load
   * @param  {String}                    [options.include[].as] The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` / `belongsTo`, this should be the singular name, and for `hasMany`, it should be the plural
   * @param  {Association}               [options.include[].association] The association you want to eagerly load. (This can be used instead of providing a model/as pair)
   * @param  {Object}                    [options.include[].where] Where clauses to apply to the child models. Note that this converts the eager load to an inner join, unless you explicitly set `required: false`
   * @param  {Array<String>}             [options.include[].attributes] A list of attributes to select from the child model
   * @param  {Boolean}                   [options.include[].required] If true, converts to an inner join, which means that the parent model will only be loaded if it has any matching children. True if `include.where` is set, false otherwise.
   * @param  {Array<Object|Model>}       [options.include[].include] Load further nested related models
Share:
12,704
lazlojuly
Author by

lazlojuly

Bugs mysteriously appear when you say, "Watch this!"

Updated on June 05, 2022

Comments

  • lazlojuly
    lazlojuly almost 2 years

    This is my very simple Sequelize model relation:

        models["Post"]
            .hasMany(models["PostLike"])
        models["PostLike"]
            .belongsTo(models["Post"])
    

    and this is my Sequelize.findAll query (written in CoffeeScript):

    Post.findAll
                include : [ PostLike ]
                where : where
                offset : start
                limit : limit
                order : order
    .success (posts) =>
         ......
    .failure (error) =>
         ......
    

    As you can see I include the PostLike model and Sequelize produces the correct LEFT JOIN:

    ...FROM "posts" LEFT JOIN "post_likes" AS "post_likes" 
        ON "posts"."id" = "posts_likes"."post_id" ...
    

    However, I would like to get Sequelize to extend the ON predicates with my custom criteria:

    ... ON "posts"."id" = "posts_likes"."post_id" AND posts_likes.author_id = 123
    

    It might be something very easy to do, I just could not find it in the docs.

    Thanks