Skip to main content

innerJoin

The innerJoin method enables you to join associations as part of your queries:

const hosts = await Host.innerJoin('places', 'rooms').all()

select "hosts".* from "hosts"
inner join "places" on "hosts"."id" = "places"."host_id"
inner join "rooms" on "places"."id" = "rooms"."place_id"
tip

Multiple string arguments describe a single traversal path (an association chain) through your associations, not parallel joins — see Association chaining for the full concept.

Join conditions​

You can also attach and, andNot, and andAny clauses to join statements. The second argument (the object) in the following code generates an and condition on the join:

const hosts = await Host.innerJoin('places', {
and: { name: 'Mountain Cabin' },
}).all()

select "hosts".* from "hosts"
inner join "places" on "hosts"."id" = "places"."host_id" and "places"."name" = $1
// An `and` statement on both `places` and `rooms`
const hosts = await Host.innerJoin(
'places',
{ and: { style: 'cabin' } },
'rooms',
{ and: { type: 'Bedroom' } }
).all()

// An `and` statement on just `rooms`
const hosts = await Host.innerJoin('places', 'rooms', {
and: { type: 'Bedroom' },
}).all()

andNot and andAny follow the same whereNot / whereAny semantics, respectively, and can appear anywhere and can:

// andNot: negate a condition on the join
const hosts = await Host.innerJoin('places', { andNot: { style: 'dump' } }).all()

// andAny: OR several conditions on the join (keys within one object are AND'd)
const hosts = await Host.innerJoin('places', {
andAny: [{ style: 'cabin' }, { style: 'treehouse' }],
}).all()