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.