Yes that works too.
But in fact I was composing some query with different reusable functions.
Here is an example of what I have.
def search_users(term, params) do
User
|> join_search_assocs
|> searchable_client()
|> search_matching(term)
|> order_search_results(term)
|> preload([u, cl, ...], client: cl)
|> Repo.paginate(params)
end
searchable_client for example is a where pipe that ensures user has :client role and an avatar. I use it in several places. Then if i want to add or remove conditions for viewable client profiles I would just rewrite that function and it will be reflected everywhere…
search_matching does something like
query
|> where([u, ..., p], ilike(u.name, ^term) or ilike(p.title, ^term))
but in more complex way since I’m searching through many joined tables and I’m also using PostgreSQL ts_vector feature.