ash-project / ash_graphql

The extension for building GraphQL APIs with Ash
https://hexdocs.pm/ash_graphql
MIT License
73 stars 49 forks source link

Filtering by relationship does not work, results in an error #189

Closed sswrk closed 4 months ago

sswrk commented 4 months ago

Describe the bug After updating Ash and extensions, filtering by relationship using a generated filter argument results in the following error:

** (ArgumentError) comparison with nil is forbidden as it is unsafe. If you want to check if a value is nil, use is_nil/1 instead

    (ecto 3.11.2) lib/ecto/query/builder.ex:1069: Ecto.Query.Builder.not_nil!/1
    (ash_postgres 1.5.28) lib/expr.ex:939: anonymous fn/3 in AshPostgres.Expr.do_dynamic_expr/6
    (ecto 3.11.2) lib/ecto/query/builder/dynamic.ex:79: Ecto.Query.Builder.Dynamic.expand/3
    (ecto 3.11.2) lib/ecto/query/builder/dynamic.ex:49: Ecto.Query.Builder.Dynamic.fully_expand/2
    (ecto 3.11.2) lib/ecto/query/builder/filter.ex:133: Ecto.Query.Builder.Filter.filter!/7
    (ash_postgres 1.5.28) lib/data_layer.ex:3201: anonymous fn/2 in AshPostgres.DataLayer.add_filter_expression/2
    (elixir 1.16.3) lib/enum.ex:2528: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ash_postgres 1.5.28) lib/data_layer.ex:3110: AshPostgres.DataLayer.filter/4
    (ash 2.21.15) lib/ash/query/query.ex:2853: Ash.Query.maybe_filter/3
    (ash 2.21.15) lib/ash/query/query.ex:2724: Ash.Query.data_layer_query/2
    (ash 2.21.15) lib/ash/actions/read/read.ex:405: anonymous fn/5 in Ash.Actions.Read.do_read/4
    (ash 2.21.15) lib/ash/actions/read/read.ex:537: Ash.Actions.Read.maybe_in_transaction/3
    (ash 2.21.15) lib/ash/actions/read/read.ex:227: Ash.Actions.Read.do_run/3
    (ash 2.21.15) lib/ash/actions/read/read.ex:50: anonymous fn/3 in Ash.Actions.Read.run/3
    (ash 2.21.15) lib/ash/actions/read/read.ex:49: Ash.Actions.Read.run/3
    (my_app 0.1.0) lib/my_app.ex:1: MyApp.read/2
    (ash_graphql 0.28.1) lib/graphql/resolver.ex:447: AshGraphql.Graphql.Resolver.resolve/2
    (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:234: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
    (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:189: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/3
    (absinthe 1.7.6) lib/absinthe/phase/document/execution/resolution.ex:174: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6

To Reproduce There are 2 resources, and there's a belongs_to relationship between them:

defmodule MyApp.ResourceA do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [AshGraphql.Resource, AshArchival.Resource]

  actions do
    read do
      primary? true
    end
  end

  attribues do
    uuid_primary_key :id

    attribue :date, :date do
      allow_nil? false
    end

    attribute :tenant_id, :uuid do
      allow_nil? false
    end
  end

  multitenancy do
    strategy :attribute
    attribute :tenant_id
    global? true
  end

  graphql do
    type :resource_a
  end
end

defmodule MyApp.ResourceA do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [AshGraphql.Resource, AshArchival.Resource]

  actions do
    read do
      primary? true
    end
  end

  attribues do
    uuid_primary_key :id

    attribute :resource_a_id, :uuid do
      allow_nil? false
    end

    attribute :tenant_id, :uuid do
      allow_nil? false
    end
  end

  multitenancy do
    strategy :attribute
    attribute :tenant_id
    global? true
  end

  relationships do
    belongs_to :resource_a, MyApp.ResourceA do
      allow_nil? false
      define_attribute? false
    end
  end

  graphql do
    type :resource_b

    queries do
      list(:resource_b, :read)
    end
  end
end

Then running this query:

query DateFilterQuery($date: String!) {
  resource_b(filter: { resource_a: { date: { eq: $date } } }) {
    id
    tenant_id
  }
}

Results in the error mentioned above.

Expected behavior

Expected not to error in this case and return properly filtered values. This worked for me with Ash 2.18.1/AshGraphql 0.26.9/AshPostgres 1.4.0/AshArchival 0.1.4.

** Runtime

Additional context I'm not sure if this is a AshGraphQL bug or Ash/AshPosgres bug.

I'll be able to start migrating to Ash 3 in a couple of weeks.

zachdaniel commented 4 months ago

Interesting... 🤔 What value is being passed for $date in that case?

sswrk commented 4 months ago

Interesting... 🤔 What value is being passed for $date in that case?

A date in the ISO format, for example "2024-07-01".

zachdaniel commented 4 months ago

Oh, sorry, I've just realized, this is for upgrading to a non 3.x version, right?

zachdaniel commented 4 months ago

I feel pretty confident that this issue is either resolved in 3.x or will be much easier to address in 3.x. Is there something forcing you to upgrade to latest 2.x version?

sswrk commented 4 months ago

Oh, sorry, I've just realized, this is for upgrading to a non 3.x version, right?

Right: Ash 2.18.2 -> 2.21.15 AshGraphql 0.26.9 -> 0.28.1 AshPostgres 1.4.0 -> 1.5.28 AshArchival 0.1.4 -> 0.1.5

Is there something forcing you to upgrade to latest 2.x version?

No, I can downgrade back to the latest version that works for me. Just wanted to upgrade to the latest 2.x version to make sure I'm in a good place to start migrating to 3.x

zachdaniel commented 4 months ago

I think that is the best choice for now TBH. Less uncertainty in general :)