absinthe-graphql / absinthe_ecto

DEPRECATED: Use dataloader
MIT License
130 stars 36 forks source link

Providing a default order for an association #7

Closed clessg closed 7 years ago

clessg commented 7 years ago

Let's say all comments should be ordered by inserted_at desc. Will Absinthe.Ecto provide functionality similar to the following?

field :comments, list_of(:comment), resolve: assoc(:comments, order_by: [desc: :inserted_at])
benwilson512 commented 7 years ago

This is an interesting question, and is really related to handling of arguments as well. Essentially what's necessary is the batching of query structs.

tlvenn commented 7 years ago

The Repo.preload function accepts a term for the field which either could be the name of the field as an atom or a two-element tuple in the form of field_name: queryable.

Could we support passing that tuple to the assoc function ?

field :comments, list_of(:comment), resolve: assoc(comments: from(c in Comment, order_by: [desc: c.inserted_at]))

This would allow filtering and ordering on an association.

mjason commented 7 years ago

May realize in this way is simple: code

resolve: assoc(:cards, from(c in Card, order_by: [desc: c.inserted_at]))
tlvenn commented 7 years ago

@benwilson512 any feedback on supporting queryable ? Thanks in advance.

benwilson512 commented 7 years ago

I'd have to investigate how it composes with Ecto.assoc. If it does so easily and someone wants to do a PR go for it! I'm focused on getting 1.3 out for now, this library will not likely get much more code from me I'm afraid until 1.3 is finished.

tlvenn commented 7 years ago

Thanks @benwilson512. If I remember correctly some discussion I have seen before with some core members of Ecto, José, among them, this is precisely how one should compose with assoc when you need to filter / order them.

Found the original issue: https://github.com/elixir-ecto/ecto/issues/659

tlvenn commented 7 years ago

Regarding the need to be able to use arguments, actually we could not map 1 to 1 to the Repo.preload but instead do something like this:

field :comments, list_of(:comment) do
  arg :top, :integer, default_value: 10
  resolve: assoc(:comments, fn query, args ->
      query
      |> order_by([desc: :popularity])
      |> limit(^min(Map.get(args, :top, 10), 100))
    end)
end
tlvenn commented 7 years ago

Let me know that you think @benwilson512 and if you like the idea, I can submit a PR.