Goal
Phoenix-Frameworkをv1.0.0にバージョンアップします。
Dev-Environment
OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.5
Phoenix Framework: v0.13.1 → v1.0.0
PostgreSQL: postgres (PostgreSQL) 9.4.4
Safetybox: v0.1.2
Scrivener: v0.11.0
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.5
Phoenix Framework: v0.13.1 → v1.0.0
PostgreSQL: postgres (PostgreSQL) 9.4.4
Safetybox: v0.1.2
Scrivener: v0.11.0
Wait a minute
Phoenix Tutorialのプロジェクトで使っている、
Phoenix-Frameworkのバージョンをv0.13.1からv1.0.0へバージョンアップします。
Phoenix-Frameworkのバージョンをv0.13.1からv1.0.0へバージョンアップします。
リリースノート調べてたけど・・・数多いな(笑)
まぁ、バージョンアップを放置していた自分の責任だな。
まぁ、バージョンアップを放置していた自分の責任だな。
ここらで一気に解消します。
Index
Rails Tutorial for Phoenix
|> Preparation
|> Version-up
|> Reflection of the version-up content
|> Extra
|> Preparation
|> Version-up
|> Reflection of the version-up content
|> Extra
Preparation
問題があっても、戻せるようにブランチを切っておきます。
>git checkout -b version_up
Switched to a new branch 'version_up'
>git branch
...
* version_up
準備良し!
Version-up
それでは、バージョンアップしましょう。
一気にバージョンアップをします。
そのためプロジェクトを新しく作成し、ソースコードを移行し、
ソースコードに必要なだけの変更をします。
そのためプロジェクトを新しく作成し、ソースコードを移行し、
ソースコードに必要なだけの変更をします。
>cd path/to/new/project
>mix phoenix.new sample_app
...
>mix ecto.create
...
>mix phoenix.server
Caution:
sample_appのDBは予め削除しておいて下さい。
同名プロジェクトで作成するとDB名が衝突します。
同名プロジェクトで作成するとDB名が衝突します。
バージョンアップ自体は、
新しくプロジェクトを作成するだけで完了です。
新しくプロジェクトを作成するだけで完了です。
Reflection of the version-up content
バージョンアップに伴う必要な変更を実施します。
ソースコードの移行を行う
移行対象のソースコード一覧。
マイグレーションファイル
- priv/repo/migrations/[timestamp]_create_user.exs
- priv/repo/migrations/[timestamp]_add_password_to_users.exs
- priv/repo/migrations/[timestamp]_create_micropost.exs
- priv/repo/migrations/[timestamp]_create_relationship.exs
静的ファイル
- priv/static/css/custom.css
lib内に作成したファイル / ディレクトリ
- lib/helpers (ディレクトリ)
- lib/helpers/pagination_helper.ex
- lib/helpers/validate_helper.ex
- lib/helpers/view_helper.ex
- lib/plugs (ディレクトリ)
- lib/plugs/check_authentication.ex
- lib/plugs/signed_in_user.ex
- lib/authentication.ex
- lib/encryption.ex
- lib/gravator.ex
- lib/sign_in.ex
Webサイト用のソースコード
Caution:
phoenix.newで生成されたソースコードは移行しません。
コントローラ
- web/controllers/micropost_controller.ex
- web/controllers/relationship_controller.ex
- web/controllers/sesion_controller.ex
- web/controllers/static_pages_controller.ex
- web/controllers/user_controller.ex
モデル
- web/models/micropost.ex
- web/models/relationship.ex
- web/models/user.ex
ビュー
- web/views/pagination_view.ex
- web/views/session_view.ex
- web/views/shared_view.ex
- web/views/static_pages_view.ex
- web/views/user_view.ex
テンプレート
- web/templates/layout/footer.html.eex
- web/templates/layout/header.html.eex
- web/templates/layout/shim.html.eex
- web/templates/pagination/pagination.html.eex
- web/templates/session/signin_form.html.eex
- web/templates/shared/*.eex
- web/templates/static_pages/*.eex
- web/templates/user/*.eex
ソースコードへ同様の設定と変更の反映を行う
ファイル: mix.exs
利用していたライブラリを追加します。
defp deps do
[...
{:safetybox, "~> 0.1"},
{:scrivener, "~> 1.0.0"}]
end
依存関係の解決を行います。
>mix deps.get
ファイル: web/router.ex
ルーティングの設定をします。
scope "/", SampleApp do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
get "/signup", UserController, :new
get "/home", StaticPagesController, :home
get "/help", StaticPagesController, :help
get "/about", StaticPagesController, :about
get "/contact", StaticPagesController, :contact
resources "/user", UserController, except: [:new]
get "user/:id/following", UserController, :following
get "user/:id/followers", UserController, :followers
get "/signin", SessionController, :new
post "/session", SessionController, :create
get "/signout", SessionController, :delete
resources "/post", MicropostController, only: [:create, :delete]
resources "/relationship", RelationshipController, only: [:create, :delete]
end
ファイル: lib/sample_app/repo.ex
Scrivenerのuseを追加します。
defmodule SampleApp.Repo do
use Ecto.Repo, otp_app: :sample_app
use Scrivener, page_size: 10
end
ファイル: web/templates/layout/app.html
以下の通り編集しました。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Sample App!!</title>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/custom.css") %>">
<%= render "shim.html" %>
</head>
<body>
<%= render "header.html", conn: @conn %>
<div class="container">
<%= @inner %>
</div>
<%= render "footer.html", conn: @conn %>
<script src="<%= static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>
ファイル: web/models/user.ex
一意性の検証を行う関数が変わったようなので修正します。
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
...
|> unique_constraint(:name)
|> unique_constraint(:email)
...
end
Description:
一意性の検証をするための関数が変わったようです。
ドキュメント: hexdocs - v1.0.1 Ecto - Changeset - unique_constraint/3
ドキュメント: hexdocs - v1.0.1 Ecto - Changeset - unique_constraint/3
ドキュメントを読んでみると、
インデックスの作成が必要と記述されています。
インデックスの作成が必要と記述されています。
ファイル: priv/repo/migration/[timestamp]_create_user.exs
インデックスを追加します。
defmodule SampleApp.Repo.Migrations.CreateUser do
use Ecto.Migration
@disable_ddl_transaction true
def change do
create table(:users) do
add :name, :string
add :email, :string
timestamps
end
create index(:users, [:name], unique: true, concurrently: true)
create index(:users, [:email], unique: true, concurrently: true)
end
end
マイグレーションを行います。
>mix ecto.migrate
...
コントローラの以下の記述を削除
plug :action
ファイル: web/controllers/page_controller.ex
以下の記述を追加します。
plug SampleApp.Plugs.CheckAuthentication
後は、コンパイルと起動を実行してみて下さい。
(一通りの機能が使えたことは確認しています)
(一通りの機能が使えたことは確認しています)
後は、ブランチをマージして削除したら終わりです。
>git checkout master
>git merge version_up
>git branch -d version_up
Extra
ちょっと修正するの忘れていた部分がありました。
ファイル: web/controllers/relationship_controller.ex
リダイレクト先をフォロー / アンフォローしたユーザページに変更します。
修正前:
def create(conn, params) do
if SampleApp.Relationship.follow!(params["id"], params["follow_id"]) do
conn = put_flash(conn, :info, "Follow successfully!!")
else
conn = put_flash(conn, :error, "Follow failed!!")
end
redirect(conn, to: static_pages_path(conn, :home))
end
def delete(conn, params) do
SampleApp.Relationship.unfollow!(params["id"], params["unfollow_id"])
conn
|> put_flash(:info, "Unfollow successfully!!")
|> redirect(to: static_pages_path(conn, :home))
end
修正後:
def create(conn, params) do
if SampleApp.Relationship.follow!(params["id"], params["follow_id"]) do
conn = put_flash(conn, :info, "Follow successfully!!")
else
conn = put_flash(conn, :error, "Follow failed!!")
end
redirect(conn, to: user_path(conn, :show, params["follow_id"]))
end
def delete(conn, params) do
SampleApp.Relationship.unfollow!(params["id"], params["unfollow_id"])
conn
|> put_flash(:info, "Unfollow successfully!!")
|> redirect(to: user_path(conn, :show, params["unfollow_id"]))
end
Speaking to oneself
一応、全部の設定は反映しているはずですが、
書き忘れている部分があるかもしれません。
書き忘れている部分があるかもしれません。
もし、何かお気づきの点、変更が足りないなど、
ご指摘などありましたら、一報頂けると助かります。
ご指摘などありましたら、一報頂けると助かります。
本当は、少しずつバージョンアップした方がいいのは分かってるんですけど、
面倒くさかったんです。(後悔はしてない)
面倒くさかったんです。(後悔はしてない)
Bibliography
Github - phoenixframework/phoenix - release note v0.14.0
Github - phoenixframework/phoenix - release note v0.15.0
Github - phoenixframework/phoenix - release note v0.16.0
Github - phoenixframework/phoenix - release note v0.16.1
Github - phoenixframework/phoenix - release note v0.17.0
Github - phoenixframework/phoenix - release note v0.17.1
Github - phoenixframework/phoenix - release note v1.0.0
hexdocs - v1.0.1 Ecto - Changeset - unique_constraint/3
Github - phoenixframework/phoenix - release note v0.15.0
Github - phoenixframework/phoenix - release note v0.16.0
Github - phoenixframework/phoenix - release note v0.16.1
Github - phoenixframework/phoenix - release note v0.17.0
Github - phoenixframework/phoenix - release note v0.17.1
Github - phoenixframework/phoenix - release note v1.0.0
hexdocs - v1.0.1 Ecto - Changeset - unique_constraint/3