Как использовать формы Phoenix для заполнения пользовательского типа в атрибуте мутации Absinthe @graphql в контроллере? - PullRequest
0 голосов
/ 11 июля 2020

Я закончил читать Создание API GraphQL в Эликсире с Абсентом (Pragprog) , и я пытаюсь расширить item_controller.ex, чтобы разрешить редактирование «пунктов меню».

I сделали эти функции в контроллере:

  @graphql """
  query ($id: ID!) {
  menu_item(id: $id) @put {
  name
  description
  }
  }
  """
  def edit(conn, %{data: %{menu_item: item}}) do
    render(conn, "edit.html", item: item)
  end

  @graphql """
  mutation UpdateMenuItem($id: ID!, $input: MenuItemInput!) {
    updatedMenuItem: updateMenuItem(id: $id, input: $input) {
      errors { key message }
      menuItem {
        name
        description
        price
      }
    }
  }
  """
  def update(conn, %{data: %{menu_item: _}}) do
    conn
    |> redirect(to: "/admin/items")
  end
  def update(conn, %{errors: errors}) do
    conn
    |> put_flash(:info, Enum.reduce(errors, "", fn e, a -> a <> e.message end))
    |> redirect(to: "/admin/items")
  end

Вот мое редактирование. html .eex:

<%= render "form.html",
Map.put(assigns, :action,
Routes.item_path(@conn, :update, @item)) %>

Вот моя форма. html .eex:

<%= form_for @conn, @action, [method: :put, as: :input], fn f -> %>
    <div class="form-group">
        <label for="description">Description</label>
        <input type="string" id="description" as="description" name="description" value="<%= @item.description %>"/>
        <label for="price">price</label>
        <input type="string" id="price" name="price" value="<%= @item.price %>"/>
        <label for="name">name</label>
        <input type="string" id="name" name="name" value="<%= @item.name %>"/>
        <label for="category">category</label>
        <input type="string" id="category" name="categoryId" value="<%= @item.category_id %>"/>
    </div>
    <%= submit "Update", class: "btn btn-primary" %>
<% end %>

Но при отправке формы я получаю сообщение об ошибке. Это ошибка:

In argument "input": Expected type "MenuItemInput!", found null.
Variable "input": Expected non-null, found null.

Мне это имеет смысл. Я мог бы, например, изменить атрибут name любого из входных элементов в form. html .eex на «input», и тогда я бы получил другую ошибку:

Argument "input" has invalid value $input.

Опять же, это делает смысл для меня. Аргумент $ input не является переменной MenuItemInput.

Итак, я ищу подход к этому одним из двух возможных способов:

  1. В форме. html. например, я создаю «форму внутри формы», чтобы у нее было поле «ввода», которое, в свою очередь, имеет несколько полей. Может быть, «группа ввода»?

  2. В item_controller я передаю переменные в атрибут модуля @graphql. Я просто не знаю, как это сделать. Я экспериментировал со множеством странного синтаксиса, потому что я даже не могу найти примеры SDL, в которых есть встроенные переменные.

Любые советы / критика / идеи очень приветствуются. Я уверен, что это сделал кто-то другой, потому что это кажется естественным попыткой после прочтения книги.

1 Ответ

1 голос
/ 11 июля 2020

Я ответил на свой вопрос! Мне просто пришлось изменить свой запрос @graphql на это:

  mutation UpdateMenuItem($id: ID!, $description: String!, $name: String!, $price: Decimal!, $categoryId: ID!) {
    update_menu_item(id: $id, input: {description: $description, name: $name, price: $price, categoryId: $categoryId}) {
      errors { key message }
      menu_item {
        name
        description
        price
      }
    }
  }

Таким образом, похоже, вы не можете использовать настраиваемые типы ввода, такие как MenuItemInput, при использовании этого атрибута модуля @graphql в контроллерах Phoenix. Также мне пришлось использовать snake-case для имен полей.

PS Я изменил подпись функции update моего контроллера на это:

def update(conn, %{data: %{update_menu_item: %{errors: nil, menu_item: menu_item}}}) do

Предупреждение всем, кто это делает - мутации, происходящие от Absinthe.Phoenix, не вызывают подписки! Вот проблема github для этой проблемы: https://github.com/absinthe-graphql/absinthe_phoenix/issues/74 Поэтому вам придется вручную опубликовать sh, если вы хотите, чтобы действия контроллера Phoenix работали с подписками.

...