Ecto ищет field_id вместо поля - PullRequest
0 голосов
/ 20 апреля 2019

Я пытаюсь настроить API-интерфейс Phoenix с помощью GraphQL.

У меня есть таблица Team и таблица Game в моей БД, например:

  schema "teams" do
    field :name, :string
    has_many :games, LvdnApi.Fixtures.Game
    timestamps()
  end

  schema "games" do
    field :away_team_score, :integer
    field :competition, :string
    field :game_datetime, :utc_datetime
    field :home_team_score, :integer
    field :round, :string
    belongs_to :home_team, LvdnApi.Fixtures.Team
    belongs_to :away_team, LvdnApi.Fixtures.Team
    timestamps()
  end

  @doc false
  def changeset(game, attrs) do
    game
    |> cast(attrs, [:home_team_score, :away_team_score, :competition, :round, :game_datetime, :home_team, :away_team])
    |> validate_required([:competition, :round, :game_datetime, :home_team, :away_team])
    |> assoc_constraint(:home_team)
    |> assoc_constraint(:away_team)
  end

И вот мои объекты в моей схеме абсента:

  object :team do
    field :id, non_null(:id)
    field :name, non_null(:string)
  end

  object :game do
    field :id, non_null(:id)
    field :home_team, :team, resolve: assoc(:home_team)
    field :away_team, :team, resolve: assoc(:away_team)
    field :home_team_score, :integer
    field :away_team_score, :integer
    field :competition, non_null(:string)
    field :round, non_null(:string)
    field :game_datetime, non_null(:datetime)
  end

Допустим, я хочу выполнить простой запрос GraphQL, например, так:

{
  allGames{
    id
    homeTeam {
      id
    }
  }
}

Я получаю следующую ошибку:

[error] #PID<0.517.0> running LvdnApiWeb.Endpoint (connection #PID<0.516.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: POST /api/v1/graphiql
** (exit) an exception was raised:
    ** (Postgrex.Error) ERROR 42703 (undefined_column) column g0.home_team_id does not exist

    query: SELECT g0."id", g0."away_team_score", g0."competition", g0."game_datetime", g0."home_team_score", g0."round", g0."home_team_id", g0."away_team_id", g0."inserted_at", g0."updated_at" FROM "games" AS g0

    hint: Perhaps you meant to reference the column "g0.home_team".
        (ecto_sql) lib/ecto/adapters/sql.ex:605: Ecto.Adapters.SQL.raise_sql_call_error/1
        (ecto_sql) lib/ecto/adapters/sql.ex:538: Ecto.Adapters.SQL.execute/5
        (ecto) lib/ecto/repo/queryable.ex:147: Ecto.Repo.Queryable.execute/4
        (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
        (lvdn_api) lib/lvdn_api_web/resolvers/fixtures_resolvers.ex:17: LvdnApiWeb.FixturesResolver.all_games/3
        (absinthe) lib/absinthe/resolution.ex:209: Absinthe.Resolution.call/2
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:209: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:168: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/4
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:153: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:72: Absinthe.Phase.Document.Execution.Resolution.walk_result/5
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:53: Absinthe.Phase.Document.Execution.Resolution.perform_resolution/3
        (absinthe) lib/absinthe/phase/document/execution/resolution.ex:24: Absinthe.Phase.Document.Execution.Resolution.resolve_current/3
        (absinthe) lib/absinthe/pipeline.ex:274: Absinthe.Pipeline.run_phase/3
        (absinthe_plug) lib/absinthe/plug.ex:421: Absinthe.Plug.run_query/4
        (absinthe_plug) lib/absinthe/plug.ex:247: Absinthe.Plug.call/2
        (phoenix) lib/phoenix/router/route.ex:39: Phoenix.Router.Route.call/2
        (phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
        (lvdn_api) lib/lvdn_api_web/endpoint.ex:1: LvdnApiWeb.Endpoint.plug_builder_call/2
        (lvdn_api) lib/plug/debugger.ex:122: LvdnApiWeb.Endpoint."call (overridable 3)"/2
        (lvdn_api) lib/lvdn_api_web/endpoint.ex:1: LvdnApiWeb.Endpoint.call/2

Как вы можете видеть, Ecto ищет home_team_id, тогда как поле в таблице Game называется home_team.

Что я могу изменить, чтобы он искал правильное имя поля?

1 Ответ

0 голосов
/ 20 апреля 2019

Я только что узнал, что проблема возникла из-за миграции, которую я не публиковал здесь (извините за это!)

У меня было:

  def change do
    create table(:games) do
      add :home_team_score, :integer
      add :away_team_score, :integer
      add :competition, :string
      add :round, :string
      add :game_datetime, :utc_datetime
      add :home_team, references(:teams, on_delete: :nothing)
      add :away_team, references(:teams, on_delete: :nothing)

      timestamps()
    end

    create index(:games, [:home_team])
    create index(:games, [:away_team])
  end

И правильный код:

def change do
    create table(:games) do
      add :home_team_score, :integer
      add :away_team_score, :integer
      add :competition, :string
      add :round, :string
      add :game_datetime, :utc_datetime
      add :home_team_id, references(:teams, on_delete: :nothing)
      add :away_team_id, references(:teams, on_delete: :nothing)

      timestamps()
    end

    create index(:games, [:home_team_id])
    create index(:games, [:away_team_id])
  end
...