SlideShare a Scribd company logo
1 of 12
5/23(月)
tokyo.ex #2 LT
@yohei_tanimoto
Phoenix Tips and Tricks
• 5/2(月)にChris McCordが、「Phoenixに関してこういうところに
注意すると良いよ」という主旨のブログを出した
• 内容は以下の3つ
1. コントローラ内でaction/2をオーバーライドする
2. ErrorViewはコントローラで直接レンダリングする
3. Task.awaitする必要がなければ、Task.asyncを使わない
本題の前に、Phoenixの処理
の流れをおさらい
かなりざっくりと…
connection
|> endpoint
|> router
|> pipelines
|> controller
詳細な足回りについては、古城さんの前回の発表資料を参考
https://speakerdeck.com/hidetakakojo/tokyo-dot-ex-number-1-
phoenixframeworkfalsezu-hui-ri
既存のPlugモジュールについては、菅原さんの前々回の発表資料を参考
http://sssslide.com/speakerdeck.com/winebarrel/elixir-meetup-number-2-
plugfalsemoziyuruwo-tong-rishi-tutemita
本題の前に、Phoenixの処理
の流れをおさらい
Controllerのところをもう少し詳しく
connection
|> controller
|> common_services
|> action
コントローラ内でaction/2を
オーバーライドする
以下の例、post_controller.ex内の「
conn.assigns.current_userへの繰り返しアクセス」があ
まりイケてない。current_user(conn)を使っても、不必要な
MAPへのアクセスが増えてベストではない。
defmodule MyApp.PostController do
use MyApp.Web, :controller
def show(conn, %{"id" => id}) do
{:ok, post} =
Blog.get_post_for_user(conn.assigns.current_user, id)
render(conn, "show.html", owner: conn.assigns.current_user,
post: post)
end
def create(conn, %{"post" => post_params}) do
{:ok, post} = Blog.publish_post(conn.assigns.current_user,
post_params)
redirect(conn, to: user_post_path(conn,
conn.assigns.current_user, post)
end
end
コントローラ内でaction/2を
オーバーライドする
以下のように action/2をオーバーライド
defmodule MyApp.PostController do
use MyApp.Web, :controller
def action(conn, _) do
args = [conn, conn.params, conn.assigns[:current_user] ||
:guest]
apply(__MODULE__, action_name(conn), args)
end
def show(conn, %{"id" => id}, current_user) do
{:ok, post} = Blog.get_post_for_user(current_user, id)
render(conn, "show.html", owner: current_user, post: post)
end
def create(conn, %{"post" => post_params}, current_user) do
{:ok, post} = Blog.publish_post(current_user, post_params)
redirect(conn, to: user_post_path(conn, current_user, post)
end
end
コントローラ内でaction/2を
オーバーライドする
複数のコントローラで呼び出したい場合は、以下のようにしてお
けば、use MyApp.Controllerでオーバーライド済み
actionを簡単に使える
defmodule MyApp.Controller do
defmacro __using__(_) do
quote do
def action(conn, _), do:
MyApp.Controller.__action__(__MODULE__, conn)
defoverridable action: 2
end
end
def __action__(controller, conn) do
args = [conn, conn.params, conn.assigns[:current_user] ||
:guest]
apply(controller, Phoenix.Controller.action_name(conn), args)
end
end
モジュール内で関数をCallす
るには
• 該当モジュール内の def または defp で定義
• import宣言により、他のモジュールからインポート
• use宣言により、該当モジュール内のdef か defp か import か
use か @before_compile に展開
• 該当モジュール内の @before_compile 属性で指定したマク
ロが def か defp か import か use に展開
ErrorViewはコントローラで
直接レンダリングする
with/elseを使えば、ステータスコードに応じて、テンプレートで
はなく、コントローラ内でエラー画面を出し分けられる(よくあるの
は、「Ecto.NoResultsError」を "404.html"テンプレート
で、 「Phoenix.ActionClauseError」を “400.html"テ
ンプレートで 等)
def create(conn, %{"post" => post_params}, current_user) do
with {:ok, post} <- Blog.publish_post(current_user, post_params) do
redirect(conn, to: user_post_path(conn, current_user, post)
else
{:error, %Ecto.Changeset{} = changeset} -> render(conn, "edit.html",
changeset: changeset)
{:error, :unauthorized} ->
conn
|> put_status(401)
|> render(ErrorView, :"401", message: "You are not authorized to
publish posts")
{:error, :rate_limited} ->
conn
|> put_status(429)
|> render(ErrorView, :"429", message: "You have exceeded the max
allowed posts for today")
end
end
Task.awaitする必要がなけれ
ば、Task.asyncを使わない
以下はOKパターン
def create(conn, %{"access_code" => code}) do
facebook = Task.async(fn -> Facebook.get_token(code) end)
twitter = Task.async(fn -> Twitter.get_token(code) end)
render(conn, "create.json", facebook: Task.await(facebook),
twitter: Task.await(twitter))
end
Task.awaitする必要がなけれ
ば、Task.asyncを使わない
以下がNGパターン
def delete(conn, _, current_user) do
{:ok, user} = Accounts.cancel_account(current_user)
Task.async(fn -> Audits.alert_cancellation_notice(user) end)
conn
|> signout()
|> put_flash(:info, "So sorry to see you go!")
|> redirect(to: "/")
end
TaskのCallerとTaskがリンクされているので、両側における異常
終了が双方に影響する。クライアントは、アカウントが削除された直後
に500エラーを受け取り、きちんとオペレーションが成功したかどうか
が分からないなど、問題がある
Task.awaitする必要がなけれ
ば、Task.asyncを使わない
以下のようにタスクをコントローラ(TaskのCaller)から切り離
し、スーパーバイザにオフロードすれば、問題解決
def delete(conn, _, current_user) do
{:ok, user} = Accounts.cancel_account(current_user)
Task.Supervisor.async_nolink(MyApp.TaskSupervisor, fn ->
Audits.alert_cancellation_notice(user) end)
end)
conn
|> signout()
|> put_flash(:info, "So sorry to see you go!")
|> redirect(to: "/")
end

More Related Content

What's hot

Vagrant intro
Vagrant introVagrant intro
Vagrant intro
t9md
 
A_road_to_AMBER_simulations_ver_1.0
A_road_to_AMBER_simulations_ver_1.0A_road_to_AMBER_simulations_ver_1.0
A_road_to_AMBER_simulations_ver_1.0
Satoshi Kume
 

What's hot (8)

Vagrant intro
Vagrant introVagrant intro
Vagrant intro
 
A_road_to_AMBER_simulations_ver_1.0
A_road_to_AMBER_simulations_ver_1.0A_road_to_AMBER_simulations_ver_1.0
A_road_to_AMBER_simulations_ver_1.0
 
擬似乱数生成器の評価
擬似乱数生成器の評価擬似乱数生成器の評価
擬似乱数生成器の評価
 
100GbE NICを使ったデータセンター・ネットワーク実証実験 -メモ-
100GbE NICを使ったデータセンター・ネットワーク実証実験 -メモ- 100GbE NICを使ったデータセンター・ネットワーク実証実験 -メモ-
100GbE NICを使ったデータセンター・ネットワーク実証実験 -メモ-
 
Microsoft open technologies の ross gardler さんを囲む会 改め 『microsoft open technolo...
Microsoft open technologies の ross gardler さんを囲む会 改め 『microsoft open technolo...Microsoft open technologies の ross gardler さんを囲む会 改め 『microsoft open technolo...
Microsoft open technologies の ross gardler さんを囲む会 改め 『microsoft open technolo...
 
MS open technologies の ross gardler さんを囲む会 改め 『MS open technologies に必ず伝えてほしい...
MS open technologies の ross gardler さんを囲む会 改め 『MS open technologies に必ず伝えてほしい...MS open technologies の ross gardler さんを囲む会 改め 『MS open technologies に必ず伝えてほしい...
MS open technologies の ross gardler さんを囲む会 改め 『MS open technologies に必ず伝えてほしい...
 
「おりこうさんな秘書」に使われている技術・手法について
「おりこうさんな秘書」に使われている技術・手法について「おりこうさんな秘書」に使われている技術・手法について
「おりこうさんな秘書」に使われている技術・手法について
 
さくらのクラウドでUCARPを使う方法 -メモ-
さくらのクラウドでUCARPを使う方法 -メモ-さくらのクラウドでUCARPを使う方法 -メモ-
さくらのクラウドでUCARPを使う方法 -メモ-
 

Recently uploaded

Recently uploaded (12)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 

For tokyo.ex #2 LT