Hey @mmport80,
This is a good question. Some of it comes down to how you want to model in the input. I think for situations like this, you probably don’t want to do an input object the way you are now.
The reason is that it implies you could do orderBy: {name: DESC, age: ASC}
. The issue is, which column will be used to sort the collection first? Age or name? GraphQL input objects are unordered just like Elixir maps, name
is not “before” age
.
This points us in a direction of looking at a list, although then the next question of course is what do we want a list of? Doing a list of the current thing won’t help much cause you could still do orderBy: [{name: DESC, age: ASC}]
. So instead let’s look at another approach:
orderBy: [{direction: DESC, value: NAME}, {direction: ASC, value: AGE}]
This lets you be a lot stricter about the types:
# on the field
arg :order_by, list_of(:user_order)
input_object :user_sort_order do
field :direction, non_null(:sort_order_direction)
field :column, non_null(:sortable_user_column)
end
enum :sort_order_direction, values: [:asc, :desc]
enum :sortable_user_column do
value :name, as: :name
value :age, as: :age
end
Now, for sure there’s some degree of duplication here in that you’ve got a variety of fields defined on your user type that you’ll also need to add to your :sortable_user_column
enum. At the present moment there isn’t much of a good way around this without doing some pretty hacky stuff.
I’m not entirely convinced though that you want it to be dynamic. I think there’s value to having the explicit list of what can be sorted by, because pretty quickly in a lot of apps this won’t be everything.