Tutorial
Step 4: Customizing Queries
So far, we’ve done fairly straightforward queries. If a user filters on
first_name
:
/api/v1/employees?filter[first_name]=Foo
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 positions
table.
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 current
means
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 ActiveRecord
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:
Then the 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
position title
.
The solution for filtering is similar:
We can now filter on title:
/api/v1/employees?filter[title]=Foo
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
use the sort
or filter
DSL, we’re just creating a sort-only or
filter-only attribute under the hood. So let’s define everything in one
shot:
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.