Ruby GraphQL: как упорядочить аргументы в опции? - PullRequest
2 голосов
/ 30 октября 2019

Я использую SearchObject с GraphQL в Ruby on Rails и создал опцию с именем: order_by

option :order_by, type: LinksOrderBy, with: :apply_order_by

Тип LinksOrderBy определяется следующим образом:

class LinksOrderBy < ::Types::BaseInputObject
  argument :created_at, AscDescEnum, required: false
  argument :description, AscDescEnum, required: false
  argument :id, AscDescEnum, required: false
  argument :updated_at, AscDescEnum, required: false
  argument :url, AscDescEnum, required: false
end

Но когда я пытаюсьчто-то вроде этого в запросе GraphQL:

{allLinks(order_by:{id: asc, description: desc}) {
    id
    description
}}

Я не получаю его в правильном порядке:

def apply_order_by(scope, value)
  scope.order(value.arguments.to_h.map{|k, v| k + ' ' + v}.join(', ')) # "description desc, id asc"
end

Как видите, правильный порядок должен быть "id, описание ", а не " описание, id ".

1 Ответ

1 голос
/ 30 октября 2019

Экземпляры ruby ​​Hash не упорядочены (см. Гарантирован ли порядок литерала хеша Ruby? )


Чтобы использовать дополнительные опции мультисортировки в типах ввода GraphQL, яобычно используют следующую структуру:

  • 1 перечисление, чтобы содержать все фильтруемые / сортируемые / доступные для поиска поля ресурса (например: UserField)
  • 1 перечисление, чтобы содержать 2 направления сортировки(asc и desc) * Поле 1014 *
  • 1, принимающее необязательный список { field: UserField!, sortDir: SortDir! } входных данных.

Это затем позволяет потребителям API просто выполнять запросы, такие как:

allUsers(sort_by: [{field: username, sortDir: desc}, {field: id, sortDir: asc}]) {
  # ...
}

И этот шаблон может быть легко повторно использован для поиска и фильтрации:

allUsers(search: [{field: username, comparator: like, value: 'bob'}]) {}
allUsers(search: [{field: age, comparator: greater_than, value: '22'}]) {} # type casting is done server-side
allUsers(search: [{field: username, comparator: equal, value: 'bob'}]) {} # equivalent of filtering

В конечном счете, при более глубокой работе вы можете разрешить сложный and / orдля ввода:

allUsers(
  search: [
    {
      left: {field: username, comparator: like, value: 'bob'}
      operator: and
      right: {field: dateOfBirth, comparator: geater_than, value: '2001-01-01'}
    }
  ]
)

Отказ от ответственности: последний пример выше - это одна из многих вещей, которые я хочу реализовать в своем GQL API, но у меня еще не было времени обдумать это, это всего лишьпроект

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...