Goal
細かい部分のリファクタリングを実施する。
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
Phoenix Tutorialのリファクタリング第四弾。
最後のリファクタリングです。
最後のリファクタリングです。
Index
Last refactoring
|> Create encrypt module
|> Unification of wording
|> Create sign-in module
|> Error message at the time of user registration
|> Delete button of Micropost
|> Extra
|> Create encrypt module
|> Unification of wording
|> Create sign-in module
|> Error message at the time of user registration
|> Delete button of Micropost
|> Extra
Create encrypt module
Userモデルから暗号化する関数を分離します。
ファイル: lib/encryption.ex
新しく暗号化を担当するモジュールを作成します。
defmodule SampleApp.Encryption do
# password decrypt
def decrypt(password) do
Safetybox.decrypt(password)
end
# password encrypt
def encrypt(password) do
Safetybox.encrypt(password, :default)
end
end
ファイル: web/models/user.ex
以下の関数を削除して下さい。
- decrypt/1
- encrypt/1
Encryptionモジュールを使用するように修正して下さい。
修正前:
def set_password_digest(changeset) do
password = Ecto.Changeset.get_field(changeset, :password)
change(changeset, %{password_digest: encrypt(password)})
end
修正後:
def set_password_digest(changeset) do
password = Ecto.Changeset.get_field(changeset, :password)
change(changeset, %{password_digest: SampleApp.Encryption.encrypt(password)})
end
ファイル: web/controllers/user_controller.ex
Encryptionモジュールを使用するように修正して下さい。
修正前:
def edit(conn, %{"id" => id}) do
user = Repo.get(SampleApp.User, id)
user = Map.put(user, :password, SampleApp.User.decrypt(user.password_digest))
changeset = SampleApp.User.changeset(user)
render(conn, "edit.html", user: user, changeset: changeset)
end
修正後:
def edit(conn, %{"id" => id}) do
user = Repo.get(SampleApp.User, id)
user = Map.put(user, :password, SampleApp.Encryption.decrypt(user.password_digest))
changeset = SampleApp.User.changeset(user)
render(conn, "edit.html", user: user, changeset: changeset)
end
Unification of wording
ログイン / ログアウト、サインイン / サインアウトと統一していない文言を使用しています。
サインインの方へ統一します。
サインインの方へ統一します。
ファイル: web/templates/session/login_form.html
ファイル名の変更。
修正前: login_form.html.eex
修正後: signin_form.html.eex
修正後: signin_form.html.eex
パラメータ名の変更。
修正前:
<%= form_for @conn, session_path(@conn, :create), [name: :login_params], fn f -> %>
修正後:
<%= form_for @conn, session_path(@conn, :create), [name: :signin_params], fn f -> %>
ファイル: web/controllers/session_controller.ex
使用するテンプレート名を修正。
修正前:
def new(conn, _params) do
render conn, login_form.html"
end
修正後:
def new(conn, _params) do
render conn, "signin_form.html"
end
パラメータ名と文言の修正。
修正前:
def create(conn, %{"login_params" => %{"email" => email, "password" => password}}) do
case login(email, password) do
{:ok, user} ->
conn
|> put_flash(:info, "User login is success!!")
|> put_session(:user_id, user.id)
|> redirect(to: static_pages_path(conn, :home))
:error ->
conn
|> put_flash(:error, "User login is failed!! email or password is incorrect.")
|> redirect(to: session_path(conn, :new))
end
end
修正後:
def create(conn, %{"signin_params" => %{"email" => email, "password" => password}}) do
case sign_in(email, password) do
{:ok, user} ->
conn
|> put_flash(:info, "User sign-in is success!!")
|> put_session(:user_id, user.id)
|> redirect(to: static_pages_path(conn, :home))
:error ->
conn
|> put_flash(:error, "User sign-in is failed!! email or password is incorrect.")
|> redirect(to: session_path(conn, :new))
end
end
flashのメッセージを修正。
修正前:
def delete(conn, _params) do
conn
|> put_flash(:info, "Logout now! See you again!!")
|> delete_session(:user_id)
|> redirect(to: static_pages_path(conn, :home))
end
修正後:
def delete(conn, _params) do
conn
|> put_flash(:info, "Sign-out now! See you again!!")
|> delete_session(:user_id)
|> redirect(to: static_pages_path(conn, :home))
end
関数名を修正。
修正前:
defp login(email, password) do
...
end
修正後:
defp sign_in(email, password) do
...
end
Safetyboxの部分で、Encryptionを使うように修正。
修正前:
defp authentication(user, password) do
case user do
nil -> false
_ ->
password == Safetybox.decrypt(user.password_digest)
end
end
修正後:
defp authentication(user, password) do
case user do
nil -> false
_ ->
password == SampleApp.Encryption.decrypt(user.password_digest)
end
end
Create sign-in module
Sessionコントローラのサインインを分離します。
ファイル: lib/sing_in_action.ex
新しくサインインを行うモジュールを作成します。
defmodule SampleApp.Signin do
import SampleApp.Authentication
def sign_in(email, password) do
user = SampleApp.User.find_user_from_email(email)
case authentication(user, password) do
true -> {:ok, user}
_ -> :error
end
end
end
Sessionコントローラの認証を分離します。
ファイル: lib/authentication.ex
新しく認証を行うモジュールを作成します。
defmodule SampleApp.Authentication do
def authentication(user, password) do
case user do
nil -> false
_ ->
password == SampleApp.Encryption.decrypt(user.password_digest)
end
end
end
ファイル: web/controllers/session_controller.ex
以下の関数を削除します。
- sign_in/2
- authentication/2
importを追加します。
import SampleApp.Signin
Error message at the time of user registration
新しくユーザを登録する時に、エラーメッセージが発生していますね。
これを修正します。
これを修正します。
ファイル: web/models/user.ex
新しく関数を作成。
def new do
%SampleApp.User{} |> cast(:empty, @required_fields, @optional_fields)
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
修正後:
def new(conn, _params) do
render(conn, "new.html", changeset: SampleApp.User.new)
end
Delete button of Micropost
自分自身の投稿以外は削除できないようにします。
ファイル: web/templates/shared/microposts.html.eex
表示中のユーザidとマイクロポストのユーザidの比較を追加しました。
修正前:
<ol class="microposts">
<li>
<%= for post <- @posts do %>
<span class="content"><%= post.content %></span>
<span class="timestamp">
Posted <%= post.inserted_at %> ago.
</span>
<%= link "Delete", to: micropost_path(@conn, :delete, post), method: :delete, class: "btn btn-danger btn-xs" %>
<% end %>
</li>
</ol>
修正後:
<ol class="microposts">
<li>
<%= for post <- @posts do %>
<span class="content"><%= post.content %></span>
<span class="timestamp">
Posted <%= post.inserted_at %> ago.
</span>
<%= if @user.id == post.user_id do %>
<%= link "Delete", to: micropost_path(@conn, :delete, post), method: :delete, class: "btn btn-danger btn-xs" %>
<% end %>
<% end %>
</li>
</ol>
Extra
ページネーションのリファクタリングをした時に修正を忘れていました。
ファイル: web/controllers/micropost_controller.ex
Micropostコントローラで、リダイレクト先を指定を修正します。
createアクションの修正。
修正前:
def create(conn, %{"micropost" => micropost_params}) do
...
action = "#{user_path(conn, :show, conn.assigns[:current_user].id)}?select_page=1"
redirect(conn, to: action)
end
修正後:
def create(conn, %{"micropost" => micropost_params}) do
...
redirect(conn, to: user_path(conn, :show, conn.assigns[:current_user]))
end
deleteアクションの修正。
修正前:
def delete(conn, %{"id" => id}) do
...
action = "#{user_path(conn, :show, conn.assigns[:current_user].id)}?select_page=1"
conn
|> put_flash(:info, "Micropost deleted successfully.")
|> redirect(to: action)
end
修正後:
def delete(conn, %{"id" => id}) do
...
conn
|> put_flash(:info, "Micropost deleted successfully.")
|> redirect(to: user_path(conn, :show, conn.assigns[:current_user]))
end
Speaking to oneself
リファクタリングをしようと思えば幾らでもできるのですが、
切りがないので、一旦これで終了します。
切りがないので、一旦これで終了します。
修正した方が良い部分などがありましたら、
ご一報頂けると助かります。
ご一報頂けると助かります。
この後は、記事の修正をします。
全記事の書き直しだ~
全記事の書き直しだ~
変更点の一覧は以下のリンク先です。
Github: darui00kara/phoenix_tutorial - finish refactoring
Github: darui00kara/phoenix_tutorial - finish refactoring
Bibliography
特になし