スポンサーリンク

2015年7月9日

[Elixir+Phoenix]User registration

Goal

ユーザ登録機能の実装。
(Implement user registration function.)

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

Wait a minute

ユーザを登録するための機能を実装する。

Index

  1. User registration form
  2. Create action
  3. Error handling
  4. Extra

1. User registration form

入力フォームを作成する。
入力項目
  • name
  • email
  • password
ファイル: web/templates/user/new.html.eex
以下のように編集する。
<%= form_for @changeset, user_path(@conn, :create), fn f -> %>
  <div class="form-group">
    <label>Name</label>
    <%= text_input f, :name, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Email</label>
    <%= text_input f, :email, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Password</label>
    <%= text_input f, :password, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= submit "Submit", class: "btn btn-primary" %>
  </div>
<% end %>
ファイル: web/controllers/user_controller.ex
newアクションを以下のように修正する。
def new(conn, _params) do
  changeset = SampleApp.User.changeset(%SampleApp.User{})
  render(conn, "new.html", changeset: changeset)
end
実行してsign upの画面を確認して下さい。
フォームが表示されています。

2. Create action

createアクションを作成する。
ファイル: web/controllers/user_controller.ex
ソースコードは以下の通り。
def create(conn, %{"user" => user_params}) do
  changeset = SampleApp.User.changeset(%SampleApp.User{}, user_params)
  Repo.insert(changeset)

  conn
  |> put_flash(:info, "User registration is success!!")
  |> redirect(to: static_pages_path(conn, :home))
end
しかし、上記のプログラムだと
不正な値があっても止まることなくDBへ登録されてしまう。

3. Error handling

登録が失敗した時の処理を追加する。
ファイル: web/controllers/user_controller.ex
エラー時の処理をcreateアクションに追加する。
def create(conn, %{"user" => user_params}) do
  changeset = User.changeset(%User{}, user_params)

  if changeset.valid? do
    Repo.insert(changeset)

    conn
    |> put_flash(:info, "User created successfully.")
    |> redirect(to: user_path(conn, :index))
  else
    render(conn, "new.html", changeset: changeset)
  end
end
現在のままだと再度、登録画面が出てくるだけで何が悪いのか分からない。
エラーメッセージを表示できるようにする。
ファイル: web/templates/user/new.html.eex
<h1>Sign up</h1>
<%= form_for @changeset, user_path(@conn, :create), fn f -> %>
  <%= if f.errors != [] do %>
    <div class="alert alert-danger">
      <p>Oops, something went wrong! Please check the errors below:</p>
      <ul>
        <%= for {attr, message} <- f.errors do %>
          <li><%= humanize(attr) %> <%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div class="form-group">
    <label>Name</label>
    <%= text_input f, :name, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Email</label>
    <%= text_input f, :email, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Password</label>
    <%= text_input f, :password, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= submit "Submit", class: "btn btn-primary" %>
  </div>
<% end %>

4. Extra

セキュアな登録を行いたい?
しかし、私も把握していない。
以下のリンク先を参考に設定して下さい。
Phoenix - Guide SSL
さて、一つ格好の悪い部分がある。
そう、成功した時のメッセージがヘッダーで被っている。
修正しよう。
メッセージは、FlashMessage機能を利用して出力している。
メッセージを送信: put_flash/2
メッセージを表示: get_flash/2
(リロードすれば画面から消えてくれる)
ファイル: web/templates/layout/header.html.eex
ソースコードは以下の通り。
<header class="navbar navbar-inverse">
  <div class="navbar-inner">
    <div class="container">
      <a class="logo" href="<%= page_path(@conn, :index) %>"></a>
      <ul class="nav nav-pills pull-right">
        <li><a href="<%= static_pages_path(@conn, :home) %>">Home</a></li>
        <li><a href="<%= static_pages_path(@conn, :help) %>">Help</a></li>
        <li><a href="<%= static_pages_path(@conn, :about) %>">About</a></li>
        <li><a href="<%= static_pages_path(@conn, :contact) %>">Contact</a></li>
        <li><a href=#>Sign in</a></li>
        <li><a href="http://www.phoenixframework.org/docs">Phoenix Get Started</a></li>
      </ul>
    </div> <!-- container -->
  </div> <!-- navbar-inner -->
</header>
<h2>
  <p class="alert alert-info" role="alert" style="text-align: center;"><%= get_flash(@conn, :info) %></p>
  <p class="alert alert-danger" role="alert" style="text-align: center;"><%= get_flash(@conn, :error) %></p>
</h2>

Speaking to oneself

どこかで見たようなコードばかりでしたね。
やっていることは車輪の再開発。
Phoenixが自動生成で吐き出してくれるコードをやっているだけです。
難しくはないですね。
今までの内容をマージすれば、
第7章のまとめがいらない気がするのですが・・・どうしましょう。
(一応作成しておきますか)
第七章が終われば、
サインイン、サインアウト機能に着手できます。
自動では生成してくれない部分をやっていくので中々面白いと思います。

Bibliography

なし

人気の投稿