Skip to content

Instantly share code, notes, and snippets.

@nicolasblanco
Created August 21, 2022 16:38
Show Gist options
  • Save nicolasblanco/7fb5fd2d9715aa1b435a331c8b0b8e78 to your computer and use it in GitHub Desktop.
Save nicolasblanco/7fb5fd2d9715aa1b435a331c8b0b8e78 to your computer and use it in GitHub Desktop.
Pagination library using Ecto
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment