Skip to content

Instantly share code, notes, and snippets.

@nicolasblanco
Created August 21, 2022 16:38

Revisions

  1. nicolasblanco created this gist Aug 21, 2022.
    41 changes: 41 additions & 0 deletions pagination.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    defmodule Pagination do
    import Ecto.Query
    alias Snippets.Repo
    #
    # ## Example
    #
    # Snippets.Snippet
    # |> order_by(desc: :inserted_at)
    # |> Pagination.page(0, per_page: 10)
    #
    def page(query, page, per_page: per_page) when is_nil(page) do
    page(query, 0, per_page: per_page)
    end

    def page(query, page, per_page: per_page) when is_binary(page) do
    page = String.to_integer(page)
    page(query, page, per_page: per_page)
    end

    def page(query, page, per_page: per_page) do
    count = per_page + 1
    result = query
    |> limit(^count)
    |> offset(^(page*per_page))
    |> Repo.all
    has_next = (length(result) == count)
    has_prev = page > 0
    total_count = Repo.one(from t in subquery(query), select: count("*"))
    page = %{
    has_next: has_next,
    has_prev: has_prev,
    prev_page: page - 1,
    next_page: page + 1,
    page: page,
    first: page*per_page+1,
    last: Enum.min([page+1*per_page, total_count]),
    count: total_count,
    list: Enum.slice(result, 0, count-1)
    }
    end
    end