Goal
Github - drewolson/scrivenerを動作検証する。
Dev-Environment
OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
Phoenix Framework: v0.13.1
PostgreSQL: postgres (PostgreSQL) 9.4.4
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
Phoenix Framework: v0.13.1
PostgreSQL: postgres (PostgreSQL) 9.4.4
Wait a minute
前回のプロジェクトをそのまま流用してもよいが、
seiten を利用した痕跡は消した方が良いです。
seiten を利用した痕跡は消した方が良いです。
プロジェクト作成(前回と同じ名前)
>cd プロジェクト作成ディレクトリ
>mix phoenix.new pagination_sample
>cd pagination_sample
>mix phoenix.server
>ctrl+c
モデル作成
>mix phoenix.gen.html User users email:string name:string
* creating priv/repo/migrations/20150720042204_create_user.exs
* creating web/models/user.ex
* creating test/models/user_test.exs
* creating web/controllers/user_controller.ex
* creating web/templates/user/edit.html.eex
* creating web/templates/user/form.html.eex
* creating web/templates/user/index.html.eex
* creating web/templates/user/new.html.eex
* creating web/templates/user/show.html.eex
* creating web/views/user_view.ex
* creating test/controllers/user_controller_test.exs
Add the resource to the proper scope in web/router.ex:
resources "/users", UserController
and then update your repository by running migrations:
$ mix ecto.migrate
>mix ecto.create
The database for PaginationSample.Repo has been created.
>mix ecto.migrate
13:29:01.698 [info] == Running PaginationSample.Repo.Migrations.CreateUser.change/0 forward
13:29:01.698 [info] create table users
13:29:01.743 [info] == Migrated in 0.3s
Description:
“resources “/users”, UserController” は、web/router.ex に追加して下さい
“resources “/users”, UserController” は、web/router.ex に追加して下さい
以降、この記事内ではプロジェクトと言ったら、
pagination_sampleを指し示す。
pagination_sampleを指し示す。
Index
- Preparation of scrivener
- Operation verification
1. Preparation of scrivener
ライブラリを利用する準備をします。
ライブラリ名: Scrivener (Github - drewolson/scrivener)
ライブラリ名: Scrivener (Github - drewolson/scrivener)
ライブラリの説明を簡単に読んでまとめてみると・・・
- Ecto クエリをページ分割できる
- paginate 関数を提供する
- ページの総数、現在ページ、現在ページのエントリとして有用な情報を提供する
- ページ分割の件数のデフォルトは10件
- Phoenix と上手く動作する
といったところです。
ファイル: mix.exs
scrivener を追加。
scrivener を追加。
defp deps do
[{:phoenix, "~> 0.13.1"},
{:phoenix_ecto, "~> 0.4"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 1.0"},
{:phoenix_live_reload, "~> 0.4", only: :dev},
{:cowboy, "~> 1.0"},
{:scrivener, "~> 0.11.0"}]
end
依存関係の解消
>mix deps.get
ライブラリの利用準備完了。
2. Operation verification
動作検証します。
ファイル: lib/pagination_sample/repo.ex
ライブラリを利用するために Repo で use する。
ライブラリを利用するために Repo で use する。
defmodule PaginationSample.Repo do
use Ecto.Repo, otp_app: :pagination_sample
use Scrivener, page_size: 10
end
ファイル: web/models/user.ex
クエリを利用するため Ecto.Query を import。
ページネーションさせる関数を追加。
クエリを利用するため Ecto.Query を import。
ページネーションさせる関数を追加。
defmodule PaginationSample.User do
use PaginationSample.Web, :model
import Ecto.Query
schema "users" do
field :email, :string
field :name, :string
timestamps
end
@required_fields ~w(email name)
@optional_fields ~w()
@doc """
Creates a changeset based on the `model` and `params`.
If `params` are nil, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
def paginate(params) do
PaginationSample.User
|> order_by([u], desc: u.name)
|> PaginationSample.Repo.paginate(page: 1, page_size: 10)
end
end
ファイル: web/controllers/user_controller.ex
indexアクションを以下のように修正。
indexアクションを以下のように修正。
def index(conn, params) do
page = User.paginate(params)
render(conn, "index.html",
users: page.entries,
page_number: page.page_number,
page_size: page.page_size,
total_pages: page.total_pages,
total_entries: page.total_entries)
end
ファイル: web/templates/user/index.html.eex
ページ情報を表示するよう修正。
ページ情報を表示するよう修正。
<div>
<p>page_number: <%= @page_number %></p>
<p>page_size: <%= @page_size %></p>
<p>total_pages: <%= @total_pages %></p>
<p>total_entries: <%= @total_entries %></p>
</div>
実行して確認してみる。
10件だけの表示は問題なし。
ページ情報も出ている。
10件だけの表示は問題なし。
ページ情報も出ている。
2ページ目の情報が欲しい場合、UserModel の paginate を以下のように修正する。
ファイル: web/models/user.ex
ファイル: web/models/user.ex
def paginate(params) do
PaginationSample.User
|> order_by([u], desc: u.name)
|> PaginationSample.Repo.paginate(page: 2, page_size: 10)
end
page: の値が変われば別のページが見れる。
この値を変更できるようにすれば、ページネーションができますね。
この値を変更できるようにすれば、ページネーションができますね。
Speaking to oneself
何この便利なライブラリ・・・It’s cool!!!!
よっしこれを使おう!
つい昨日まで悩んできたのに現金なことですが(笑)
つい昨日まで悩んできたのに現金なことですが(笑)
表示部分とページ遷移部分を付け足してやれば、
ページネーション機能の実装も楽勝ですな!!(笑)
ページネーション機能の実装も楽勝ですな!!(笑)
ライブラリの作者がページネーションを実装している記事が見つかりました。
リンク先を見れば内部で、どうやって動作しているかが理解できると思います。
Pagination with Phoenix & Ecto
リンク先を見れば内部で、どうやって動作しているかが理解できると思います。
Pagination with Phoenix & Ecto