How do I sort records by random in the resource action?

Hi all,

Is there a way to sort by random in the read actions?
I did it before with Ecto and fragment(“RANDOM()”), but not sure how to do it with Ash.
Whenever I try to use fragment in prepare statement in the resource action, I constantly getting undefined function fragment/1.
No matter which module do I import on the top of the resource.

Right now, the way to use expressions in sorts is to use calculations. Using calculations you can technically do anything you want, but I’ve just pushed something to main to make this nicer that you may want to try out. It’s a tool called Ash.Sort.expr_sort/1. Here is what it would look like:

require Ash.Sort # up at the top
read :random do
  prepare fn query, _ -> 
    Ash.Query.sort(query, Ash.Sort.expr_sort(fragment("RANDOM()")))

For context, this basically allows easily using an expression instead of a field. I will make this more ergonomic later, but this is a reasonable way to do it until 3.0. To change sort order, or multiple expressions, you’d do:

Ash.Query.sort(query, [{Ash.Sort.expr_sort(foo), :asc}, {Ash.Sort.expr_sort(bar), :desc}])

This also, FWIW allows sorting on related fields without requiring an aggregate be added

Ash.Query.sort(query, Ash.Sort.expr_sort(first(owner, field: :employee_code)))

The thing I mentioned requires using ash from the main branch to try it out. I’ll deploy it sometime in the next few days. {:ash, github: "ash-project/ash"}

This is awesome! Thank you very much

1 Like