diff --git a/src/database/query_builder/chainable.ts b/src/database/query_builder/chainable.ts index 7839ff3e..d7ec061b 100644 --- a/src/database/query_builder/chainable.ts +++ b/src/database/query_builder/chainable.ts @@ -231,8 +231,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { */ protected transformValue(value: any) { if (value instanceof Chainable) { - value.applyWhere() - return value.knexQuery + return value.toKnex() } if (value instanceof ReferenceBuilder) { @@ -2074,4 +2073,12 @@ export abstract class Chainable extends Macroable implements ChainableContract { return this } + + /** + * Applies statements and returns knex query + */ + toKnex() { + this.applyWhere() + return this.knexQuery + } } diff --git a/src/orm/relations/base/query_builder.ts b/src/orm/relations/base/query_builder.ts index f4b0e5e6..116c56f4 100644 --- a/src/orm/relations/base/query_builder.ts +++ b/src/orm/relations/base/query_builder.ts @@ -165,6 +165,14 @@ export abstract class BaseQueryBuilder return this } + /** + * Return knex query + */ + toKnex() { + this.applyConstraints() + return super.toKnex() + } + /** * Get query sql */ diff --git a/test/orm/model_query_builder.spec.ts b/test/orm/model_query_builder.spec.ts index e90ac83f..83b2fdfe 100644 --- a/test/orm/model_query_builder.spec.ts +++ b/test/orm/model_query_builder.spec.ts @@ -10,7 +10,7 @@ import { test } from '@japa/runner' import { AppFactory } from '@adonisjs/core/factories/app' -import { column } from '../../src/orm/decorators/index.js' +import { column, hasMany } from '../../src/orm/decorators/index.js' import { scope } from '../../src/orm/base_model/index.js' import { ModelQueryBuilder } from '../../src/orm/query_builder/index.js' import { @@ -21,6 +21,7 @@ import { resetTables, getBaseModel, } from '../../test-helpers/index.js' +import { HasMany } from '../../src/types/relations.js' test.group('Model query builder', (group) => { group.setup(async () => { @@ -443,4 +444,51 @@ test.group('Model query builder', (group) => { const users = await User.query().count('* as total') assert.equal(Number(users[0].$extras.total), 2) }) + + test('apply relationship constraints when using sub query', async ({ fs, assert }) => { + const app = new AppFactory().create(fs.baseUrl, () => {}) + await app.init() + const db = getDb() + const adapter = ormAdapter(db) + const BaseModel = getBaseModel(adapter) + + class Post extends BaseModel { + @column() + declare userId: number | null + + @column() + declare title: string + } + + class User extends BaseModel { + @column({ isPrimary: true }) + declare id: number + + @column() + declare username: string + + @hasMany(() => Post) + declare posts: HasMany + } + + Post.boot() + User.boot() + + const users = await User.createMany([ + { + username: 'virk', + }, + { + username: 'nikk', + }, + ]) + + for (let user of users) { + await user.related('posts').create({ title: 'Test' }) + } + + const posts = await Post.query().whereIn('id', users[0].related('posts').query().select('id')) + + assert.lengthOf(posts, 1) + }) })