Conditional joins with Hanami

Conditional join is very useful concept that allows to filter records before joining them with other collection. It’s helpful when finding a record without specific association is desired.

Imagine we want to find users who don’t have any published posts:

SELECT users.*
FROM users
LEFT JOIN posts ON = posts.user_id
AND posts.status = 'published'

We filter posts (to include only published ones) before joining them with users to ensure only published posts are included in the collection. Once we have it, we can filter users without posts out (WHERE IS NULL).

If we move the condition from JOIN to WHERE clause, we will receive no results. Firstly, database joins all users with their posts and then try to include only those, whose posts are published and those who doesn’t have any posts at the same time. This condition is actually impossible - posts can’t be filtered based on their status if they don’t exist.

Using Hanami repositories, we can create above query as follows:

    posts[:user_id].qualified => users[:id].qualified,
    status: 'published'
  .where(posts[:id].qualified => nil)