radmen / adonis-lucid-soft-deletes

Experimental implementation of soft-deletes for Adonis Lucid

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does not add where condition using `withCount` when referencing itself

MZanggl opened this issue · comments

I found the following case where the where condition is not being added automatically.
Say you have a table that holds comments. You can reply to a comment which is recorded in the same table, but with the field reply_to_comment_id filled.

We then have a query that gets all the comments and the number of replies it received.

This is the model:

const Model = use('Model')

class Comment extends Model {
  static boot () {
    super.boot()

    this.addTrait('@provider:Lucid/SoftDeletes')
  }

  replies() {
    return this.hasMany('App/Models/Comment', 'id', 'reply_to_comment_id')
  }
}

module.exports = Comment

And here I prepared a test that demonstrates the scenario:

test('...', async ({ assert }) => {
  const comment= await Factory.model('App/Models/Comment').create()
  await Factory.model('App/Models/Comment').create({ reply_to_comment_id: comment.id })
  await Factory.model('App/Models/Comment').createMany(2, {
    reply_to_comment_id: comment.id,
    deleted_at: '2019-01-01',
  })

  const replies = await Comment.query().whereNull('reply_to_comment_id').withCount('replies').fetch()
  assert.equal(replies.rows[0].toJSON().__meta__.replies_count, 1)
})

The above fails because replies_count is 3 instead of just one.
The following workaround is necessary:

Comment.query().withCount('replies', (builder) => {
  builder.whereNull('deleted_at')
})

@MZanggl good catch. Thank you for that!

I can confirm that this bug is in the trait. It incorrectly adds the table name to the conditions.
In the example you've added the query looks like:

select *, (select count(*) from `comments` as `sj_0` where `comments`.`id` = `sj_0`.`reply_to_comment_id` and `comments`.`deleted_at` is null) as `replies_count` from `comments` where `reply_to_comment_id` is null and `comments`.`deleted_at` is null limit ?

The comments.deleted_at in the subquery should be replaced with sj_0.deleted_at. I'll try to investigate this and see what can be done.

@MZanggl I've published v0.1.4 which should contain a fix for your issue.