Skip to content

Instantly share code, notes, and snippets.

@bluzky
Last active May 11, 2018 06:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluzky/b610271c20d2e2cc0384a02fcdfef481 to your computer and use it in GitHub Desktop.
Save bluzky/b610271c20d2e2cc0384a02fcdfef481 to your computer and use it in GitHub Desktop.
Elixir Phoenix pagination module from https://blog.drewolson.org/pagination-with-phoenix-ecto/
defmodule Infra.Paginator do
import Ecto.Query
alias Infra.Repo
defstruct [:entries, :page, :size, :total]
def new(query, params) do
page_number = params |> Map.get("page", 1) |> to_int
page_size = params |> Map.get("size", 10) |> to_int
%Infra.Paginator{
entries: entries(query, page_number, page_size),
page: page_number,
size: page_size,
total: total_pages(query, page_size)
}
end
defp entries(query, page_number, page_size) do
offset = page_size * (page_number - 1)
query
|> limit(^page_size)
|> offset(^offset)
|> Repo.all()
end
defp to_int(i) when is_integer(i), do: i
defp to_int(s) when is_binary(s) do
case Integer.parse(s) do
{i, _} -> i
:error -> :error
end
end
defp total_pages(query, page_size) do
count =
query
|> exclude(:order_by)
|> exclude(:preload)
|> exclude(:select)
|> select([e], count(e.id))
|> Repo.one()
trunc(Float.ceil(count / page_size))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment