Slide 1

Slide 1 text

before action setter いる? 2018-09-06 表参道.rb #38 1

Slide 2

Slide 2 text

自己紹介 • @s_osa_ • OSA Shunsuke • Cookpad Inc. • 技術部 ユーザー・決済基盤グループ • Rails に対しては愛憎相半ばする複雑な気持ちを抱い ている 2

Slide 3

Slide 3 text

話すこと • before action setter って必要? • 多くの場合、いらないのでは? 3

Slide 4

Slide 4 text

before action setter 名前がないといろいろ不便なので、勝手に before action setter と呼んでいますが、要は scaffold でも生成されるこいつ。 class HogesController < ApplicationController before_action :set_hoge, only: %i[show] private def set_hoge @hoge = Hoge.find(params[:id]) end end 4

Slide 5

Slide 5 text

つらい理由 5

Slide 6

Slide 6 text

変数の初期化・代入を目的としたメソッド set_* を呼ぶと、メソッド呼び出し側にインスタンス変数 が増えるという重大かつ直感的でないな副作用がある。 普段コードを書くときに def set_message @message = 'Hello' end set_message みたいなことをする人はまずいないはず。 6

Slide 7

Slide 7 text

自明でない順序依存性が発生しがち はじめはシンプルだった before action setter も、機能 追加などをしていくうちに、いつの間にか before_action :set_hoge before_action :set_fuga before_action :set_foo # set_bar ΑΓઌʹ࣮ߦ͢Δ͜ͱʂʂ before_action :set_bar のようなことになりがち。 7

Slide 8

Slide 8 text

action の関心がわかりにくい Rails の controller におけるインスタンス変数は view で 参照する変数であり、レスポンスを組み立てるために必要 なものが入っている。 インスタンス変数が暗黙的に代入されると、その action の関心が何なのかが少なくともパッとはわからない。 8

Slide 9

Slide 9 text

じゃあ、どう書くか 9

Slide 10

Slide 10 text

シンプルなとき そのまま書けば良い。 class HogesController < ApplicationController def show @hoge = Hoge.find(params[:id]) end def edit @hoge = Hoge.find(params[:id]) end # ... end 10

Slide 11

Slide 11 text

複雑・重要な絞り込みがあるとき 具体的には、複雑だったり重要だったりする絞り込みを行なっていて、その重複を避けたい場合。 そういうときは set_* じゃなく find_* する。 class HogesController < ApplicationController def show @hoge = find_hoge(params[:id]) end private # @param id [String] # @return [Hoge] def find_hoge(id) Hoge.very.complex.condtion.find(id) end end 11

Slide 12

Slide 12 text

順序依存性があるとき 複数の before action setter の間に順序依存性があったケースでは依存を明確にして管理するために引数として渡す。 class HogesController < ApplicationController def show @hoge = find_hoge(params[:id]) @fuga = find_fuga(@hoge) end private # @param id [String] # @return [Hoge] def find_hoge(id) Hoge.very.complex.condtion.find(id) end # @param hoge [Hoge] # @return [Fuga] def find_fuga(hoge) hoge.fugas.very.important.condition.first end end 12

Slide 13

Slide 13 text

before action を使うべきとき 13

Slide 14

Slide 14 text

認証・検証など • action が呼ばれる際に満たしておく事前条件のようなものが存 在し、その条件を満たさないときは action を実行しないような 類のもの。 •authenticate_*! とか verify_*! みたいなメソッド名が 多い。 • 別の言い方をすると、before_action の旧名である before_filter という名前がしっくり来る感じのやつ。 •setter じゃないことも多いが、認証・検証後に set することもあ りがち。 14

Slide 15

Slide 15 text

横断的に使用される変数など • 典型的には set_current_user のようなもの。 • そのアプリケーションで横断的に使われる変数などの初期 化・代入。 •広く使われるものであれば、そのアプリケーションを開発 する人の基礎知識とすることに妥当性が生まれる。 • 横断的に使用されるという性質上、この種の before action setter は ApplicationController や Admin::BaseController のような場所に定義される。 15

Slide 16

Slide 16 text

まとめ 16

Slide 17

Slide 17 text

まとめ • before action setter って必要? • 多くの場合、いらない。 • Rails とはいい感じに折り合いをつけて付き合っていきた い。 17

Slide 18

Slide 18 text

Thank You! 18