phoenixのサンプルに画面を追加する

※本記事は、基本的に[公式ページ](http://www.phoenixframework.org/docs/adding-pages)を試し、まとめた内容となっています。
*今回の内容は[git](https://github.com/kashiwaguma-hiro/hello_phoenix)にあります。

# 目的
[前回作成したサンプル](http://qiita.com/kashiwaguma-hiro/items/f2292b67b8729df89264)に、ページを新たに追加する方法をまとめる。

# ページの追加方法

1.新ページのパス設定を追加

編集ファイル： web/router.ex

```erlang
  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/hello", HelloController, :index  ←追加した行
  end

# ※追加した行の説明
# 
# get がHTTPリクエストメソッド
# "/hello"　がパス
# HelloController が　/hello　へ来たアクセスを処理するエンドポイント
# :index が HelloController　のどの関数と紐付けるかを表現

```


2.HelloControllerを作成

作成ファイル： web/controllers/hello_controller.ex

```erlang
defmodule HelloPhoenix.HelloController do
  use HelloPhoenix.Web, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end
```

3.HelloControllerに対応する viewクラスを定義

作成ファイル： web/views/hello_view.ex

```erlang
defmodule HelloPhoenix.HelloView do
  use HelloPhoenix.Web, :view
end
```

※ コントローラのファイル名の `_` で区切った前方が一致している必要がある。
  今回のケースだと「hello_」の部分が一致していないとだめ。

```bash
web/controllers/hello_controller.ex
web/views/hello_view.ex
```

4.実際に描画するhtmlファイルを用意

作成ファイル：web/templates/hello/index.html.eex

```html
<div class="jumbotron">
  <h2>Hello World, from Phoenix!</h2>
</div>
```

※htmlファイルの場合も、templatesの下に掘るフォルダは hello　で統一。

５． http://localhost:4000/hello にアクセスすると、その時点で helloページが表示される！

![image](https://qiita-image-store.s3.amazonaws.com/0/101891/f0874473-2409-f0e3-fcf9-0673e11d64fc.png)


※ webディレクトリ配下はサーバの再起動無しに勝手にコンパイルされる。

# パラメータを受け取るページの追加

1.新ページのパス設定を追加

```erlang

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/hello", HelloController, :index
    get "/hello/:messenger", HelloController, :show  ←追加行
  end
```

:messenger が入ったパス定義を追加し、 HelloControllerの showメソッドに紐付けた。

2.HelloController に showメソッドを定義

編集ファイル：web/controllers/hello_controller.ex

```erlang

  def show(conn, %{"messenger" => messenger}) do
    render conn, "show.html", messenger: messenger
  end
```
showの第二引数がパラメータを受け取るよう定義された。
描画するページは `show.html` と定義した。

3.描画するページを作成

作成ファイル： web/templates/hello/show.html.eex

```erlang
<div class="jumbotron">
  <h2>Hello World, from <%= @messenger %>!</h2>
</div>
```

<%= @messenger %>　という定義があるが、これは先程のパラメータ messengerを参照して表示するという内容となっている。


4.http://localhost:4000/hello/Hoge にアクセス

パスパラメータとして設定した `Hoge` が画面に表示されていることが確認できた！
![image](https://qiita-image-store.s3.amazonaws.com/0/101891/52dc5bd2-5717-c93b-ed12-35c5343c6cda.png)



# 【補足】テンプレートの構成

`web/templates/layout/app.html.eex`を参照すると

```html
      <main role="main">
        <%= render @view_module, @view_template, assigns %>
      </main>
```

という記述がある。
実はこのlayoutが基本的なページレイアウトで、先程追加したページは、基本レイアウトに埋め込まれて表示される部分となっている。

![image](https://qiita-image-store.s3.amazonaws.com/0/101891/7271d6e2-10eb-0d67-1a24-54ff67eaa93d.png)



# 【補足】便利な router定義 resources

ユーザの登録・一覧・編集・削除を提供するアプリを作成する場合、上記のような定義だと一つ一つコントローラ定義をしないといけない...と思いきや

http://www.phoenixframework.org/docs/routing#section-resources

で示される resources を使うと

```erlang
scope "/", HelloPhoenix do
  pipe_through :browser # Use the default browser stack

  get "/", PageController, :index
  resources "/users", UserController　　←追加行
end
```

と定義するだけで、下記のコントローラ定義をしたことになる！楽ちん！

```erlang
user_path  GET     /users           HelloPhoenix.UserController :index
user_path  GET     /users/:id/edit  HelloPhoenix.UserController :edit
user_path  GET     /users/new       HelloPhoenix.UserController :new
user_path  GET     /users/:id       HelloPhoenix.UserController :show
user_path  POST    /users           HelloPhoenix.UserController :create
user_path  PATCH   /users/:id       HelloPhoenix.UserController :update
           PUT     /users/:id       HelloPhoenix.UserController :update
user_path  DELETE  /users/:id       HelloPhoenix.UserController :delete
```

resourcesはネスト定義できます。
想像どおりかと思いますが、

```erlang
  resources "/users", UserController do
    resources "/posts", PostController
  end
```

と `/posts`のr resources定義を加えると、以下のようなパスで定義できます。

```erlang
user_post_path  GET     users/:user_id/posts           HelloPhoenix.PostController :index
user_post_path  GET     users/:user_id/posts/:id/edit  HelloPhoenix.PostController :edit
user_post_path  GET     users/:user_id/posts/new       HelloPhoenix.PostController :new
user_post_path  GET     users/:user_id/posts/:id       HelloPhoenix.PostController :show
user_post_path  POST    users/:user_id/posts           HelloPhoenix.PostController :create
user_post_path  PATCH   users/:user_id/posts/:id       HelloPhoenix.PostController :update
                PUT     users/:user_id/posts/:id       HelloPhoenix.PostController :update
user_post_path  DELETE  users/:user_id/posts/:id       HelloPhoenix.PostController :delete
```


# まとめ
前回と今回で、基本的な枠組み作成、画面遷移の定義、作成方法を学ぶことができました。
次回は、ドメイン実装あたりにフォーカスして学べたら良いかなと思います。