Step 4: Customizing Queries
So far, we’ve done fairly straightforward queries. If a user filters on
We’ll query the equivalent database column:
But what if there’s more complex logic? Let’s say we want to sort
Employees on their
title - which comes from the
How would that work?
The Rails Stuff 🚂
First, we need to get data for an Employee’s current position.
Let’s start by defining what
See the ActiveRecord Scopes documentation if you’re unfamiliar with this concept.
Reference this scope in a new association:
Before moving on, let’s review what we need to do. The
code for sorting Employees on their current position’s title would be:
Let’s wire this up to Graphiti:
The Graphiti Stuff 🎨
We’re only going to sort and filter on the
title attribute -
never display or persist. So start by defining the attribute as such:
sort DSL to place our custom query:
That’s it! When a request to sort on the title comes in, we’ll alter our
scope to join on the
positions table, and order based on the current
The solution for filtering is similar:
We can now filter on title:
Let’s do one more example - how would we order Employees by department name? We could start the same way:
But if we’re only sorting, this is actually redundant. Whenever we
filter DSL, we’re just creating a sort-only or
filter-only attribute under the hood. So let’s define everything in one
Remember: you only need to pass the type as the second argument when an attribute doesn’t already exist. And if you ever get an error saying something is unfilterable or unsortable, check to see if you’ve already defined a filter-only or sort-only attribute using these methods.
Digging Deeper 🧐
There’s a critical part of Graphiti that makes everything easier: start by imagining it doesn’t exist.
In other words, the meat of the logic above had nothing to do with Graphiti code - we’re simply “wiring up” independent ActiveRecord queries. If you’re ever confused about query logic, get things working without Graphiti first.
We could have changed the above to ActiveRecord scopes like
.order_by_title(title), making the wiring code even simpler. Consider
doing this when the logic is reusable or particlar complex, but be aware
of the tradeoffs of double-testing units.