drikanius

drikanius

I have a resource that uses pagination and also sort by inserted_at

Until version 2.18 it worked fine even using timestamps(). Currently I’m on master and I noticed that pagination only works properly when I use timestamps(private?: false)

I tried to create a test based on pagination_test.exs (from master)

defmodule Ash.Actions.PaginationTest do
  use ExUnit.Case, async: true

  require Ash.Query

  defmodule Post do
    @moduledoc false
    use Ash.Resource, data_layer: Ash.DataLayer.Ets

    ets do
      private?(true)
    end

    attributes do
      uuid_primary_key :id

      attribute :user_id, :uuid
      attribute :body, :string

      timestamps()
    end

    actions do
      defaults [:create, :update, :destroy]

      read :read do
        primary? true
        pagination offset?: true, required?: true, default_limit: 25
      end

      read :read_and_sort do
        pagination keyset?: true, required?: true, default_limit: 25

        prepare build(sort: [inserted_at: :desc])
      end
    end

    relationships do
      belongs_to :user, Ash.Actions.PaginationTest.User, define_attribute?: false
    end
  end

  defmodule User do
    # same
  end

  defmodule Registry do
    @moduledoc false
    use Ash.Registry

    entries do
      entry User
      entry Post
    end
  end

  defmodule Api do
    use Ash.Api

    resources do
      registry Registry
    end
  end

# ... 

  describe "testing timestamp sort" do
    setup do
      for i <- 0..9 do
        user = Api.create!(Ash.Changeset.new(User, %{name: "#{i}"}))

        if i != 0 do
          for x <- 1..i do
            Api.create!(Ash.Changeset.new(Post, %{body: "#{i}-#{x}", user_id: user.id}))
          end
        end
      end

      :ok
    end

    @tag :wip
    test "todo" do

      page = Ash.Query.for_read(Post, :read_and_sort) |> Api.read!(page: [limit: 1])

      cursor = List.last(page.results).__metadata__.keyset

      page_2 = Ash.Query.for_read(Post, :read_and_sort) |> Api.read!(page: [limit: 1, after: cursor])

      dbg(page_2)
    end
  end
end

When calling the second read (using after and cursor) I got an error:

 ** (MatchError) no match of right hand side value: {#Ash.Query<resource: Ash.Actions.PaginationTest.Post, sort: [inserted_at: :desc, id: :asc], limit: 2, errors: [%Ash.Error.Query.NoSuchAttributeOrRelationship{attribute_or_relationship: :inserted_at, resource: Ash.Actions.PaginationTest.Post, changeset: nil, query: nil, error_context: [], vars: [], path: [:filter], stacktrace: #Stacktrace<>, class: :invalid}], select: [:id, :inserted_at, :user_id, :body, :updated_at]>, []}
     code: page_2 = Ash.Query.for_read(Post, :read_and_sort) |> Api.read!(page: [limit: 1, after: cursor])
     stacktrace:
       (ash 2.18.1) lib/ash/actions/read/read.ex:352: anonymous fn/5 in Ash.Actions.Read.do_read/4
       (ash 2.18.1) lib/ash/actions/read/read.ex:472: Ash.Actions.Read.maybe_in_transaction/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:200: Ash.Actions.Read.do_run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:49: anonymous fn/3 in Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:48: Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/api/api.ex:2415: Ash.Api.read!/3
       test/actions/pagination_test.exs:906: (test)

Observation:

  1. Does not use inserted_at to sort make the code works
  2. Uses timestamps(private?: false), instead of timestamps(), also make it works

Is this the expected behavior (using private?: false) or am I doing something wrong?

Showing Posts 1 to 5

zachdaniel

zachdaniel

Creator of Ash

Interesting…I’m not sure what the root issue might be, but I’ve pushed a fix for that specific stack trace that might allow us to gather some more information. We were using left = right in a with statement, which was a typo as we meant to be using left <- right.

drikanius

drikanius OP

Well… after pull the error change at least. Still only works with private?: false :smiling_face_with_tear:

** (Ash.Error.Invalid) Input Invalid

     * No such attribute or relationship :inserted_at for Ash.Actions.PaginationTest.Post
         at filter
       (elixir 1.16.0) lib/process.ex:860: Process.info/2
       (ash 2.18.1) lib/ash/error/exception.ex:50: Ash.Error.Query.NoSuchAttributeOrRelationship.exception/1
       (ash 2.18.1) lib/ash/filter/filter.ex:2754: Ash.Filter.add_expression_part/3
       (ash 2.18.1) lib/ash/filter/filter.ex:2332: anonymous fn/3 in Ash.Filter.parse_expression/2
       (elixir 1.16.0) lib/enum.ex:4842: Enumerable.List.reduce/3
       (elixir 1.16.0) lib/enum.ex:2582: Enum.reduce_while/3
       (ash 2.18.1) lib/ash/filter/filter.ex:3566: Ash.Filter.parse_and_join/3
       (ash 2.18.1) lib/ash/filter/filter.ex:2376: Ash.Filter.add_expression_part/3
       (ash 2.18.1) lib/ash/filter/filter.ex:2332: anonymous fn/3 in Ash.Filter.parse_expression/2
       (elixir 1.16.0) lib/enum.ex:4842: Enumerable.List.reduce/3
       (elixir 1.16.0) lib/enum.ex:2582: Enum.reduce_while/3
       (ash 2.18.1) lib/ash/filter/filter.ex:256: Ash.Filter.parse_input/5
       (ash 2.18.1) lib/ash/query/query.ex:270: Ash.Query.filter_input/2
       (ash 2.18.1) lib/ash/actions/read/read.ex:1717: Ash.Actions.Read.keyset_pagination/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:1659: Ash.Actions.Read.do_paginate/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:297: anonymous fn/5 in Ash.Actions.Read.do_read/4
       (ash 2.18.1) lib/ash/actions/read/read.ex:472: Ash.Actions.Read.maybe_in_transaction/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:200: Ash.Actions.Read.do_run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:49: anonymous fn/3 in Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:48: Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/api/api.ex:2415: Ash.Api.read!/3
       test/actions/pagination_test.exs:906: Ash.Actions.PaginationTest."test testing timestamp sort ahoy"/1
       (ex_unit 1.16.0) lib/ex_unit/runner.ex:472: ExUnit.Runner.exec_test/2
       (stdlib 5.0.2) timer.erl:270: :timer.tc/2
       (ex_unit 1.16.0) lib/ex_unit/runner.ex:394: anonymous fn/6 in ExUnit.Runner.spawn_test_monitor/4
     code: page_2 = Ash.Query.for_read(Post, :read_and_sort) |> Api.read!(page: [limit: 1, after: cursor])
     stacktrace:
       (elixir 1.16.0) lib/process.ex:860: Process.info/2
       (ash 2.18.1) lib/ash/error/exception.ex:50: Ash.Error.Invalid.exception/1
       (ash 2.18.1) lib/ash/error/error.ex:606: Ash.Error.choose_error/2
       (ash 2.18.1) lib/ash/error/error.ex:260: Ash.Error.to_error_class/2
       (ash 2.18.1) lib/ash/actions/read/read.ex:257: Ash.Actions.Read.do_run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:49: anonymous fn/3 in Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/actions/read/read.ex:48: Ash.Actions.Read.run/3
       (ash 2.18.1) lib/ash/api/api.ex:2415: Ash.Api.read!/3
       test/actions/pagination_test.exs:906: (test)
zachdaniel

zachdaniel

Creator of Ash

Okay, try again :slight_smile:

drikanius

drikanius OP

Yay!!! Working

Thank you :partying_face: :partying_face:

zachdaniel

zachdaniel

Creator of Ash

My pleasure! Thanks for the report :slight_smile:

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews