Better way to do this query?

I have a simple search action for an autocomplete, and I want to have it skip the filter if the search term is "" in order to just return the top sorted options. I have a pretty simple solution, but was wondering if there's a cleaner/more idiomatic way of doing it:
read :autocomplete do
argument :search, :ci_string

prepare fn query, _ ->
search_string = Ash.Query.get_argument(query, :search)

query
|> Ash.Query.filter(
if ^search_string != "", do: contains(name_email, ^search_string), else: true
)
|> Ash.Query.load(:name_email)
|> Ash.Query.sort(:name_email)
|> Ash.Query.limit(10)
end
end
read :autocomplete do
argument :search, :ci_string

prepare fn query, _ ->
search_string = Ash.Query.get_argument(query, :search)

query
|> Ash.Query.filter(
if ^search_string != "", do: contains(name_email, ^search_string), else: true
)
|> Ash.Query.load(:name_email)
|> Ash.Query.sort(:name_email)
|> Ash.Query.limit(10)
end
end
If not, no problem, this works fine. 🙂
11 Replies
ZachDaniel
ZachDaniel•3y ago
🤔 Can search_string ever be ""? IIRC we trim strings by default
frankdugan3
frankdugan3OP•3y ago
Seems to work as expected. When I empty the search field, I get the top 10, when I enter any character it starts filtering. Trim can produce an empty string, right? That's what I'm matching on.
ZachDaniel
ZachDaniel•3y ago
Sorry, its actually allow_empty? which defaults to false and should be doing "" -> nil if its not then something weird is going on TBH
frankdugan3
frankdugan3OP•3y ago
Oh, interesting... When I inspect the search term, it is nil. :thinkinghard: Is it because of the interpolation?
ZachDaniel
ZachDaniel•3y ago
oh, lol search_string != "" is false when search_string is NULL
frankdugan3
frankdugan3OP•3y ago
iex(46)> nil != ""
true
iex(47)> "#{nil}" != ""
false
iex(46)> nil != ""
true
iex(47)> "#{nil}" != ""
false
ZachDaniel
ZachDaniel•3y ago
because ash expressions are SQL-ish
frankdugan3
frankdugan3OP•3y ago
Yeah, that makes sense. Which is all good, that's the behavior I'm looking for.
ZachDaniel
ZachDaniel•3y ago
well, technically it evalutest to NULL but yeah it causes the else branch to run
frankdugan3
frankdugan3OP•3y ago
I'm just wondering if there's a better abstraction for this sort of "don't filter empty search strings" idea. I'll be writing a lot of these kinds of actions. And some of them will have much more complex filtering.
ZachDaniel
ZachDaniel•3y ago
Hm…maybe a custom helper macro like filter_if(predicate, …)

Did you find this page helpful?