controllerのbefore_actionにおける インスタンス変数セットについて
TRANSCRIPT
![Page 1: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/1.jpg)
Controllerのbefore_actionにおけるインスタンス変数セットについて
![Page 2: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/2.jpg)
自己紹介名前 : pospomeブログ : http://d.hatena.ne.jp/pospome/職種 : サーバサイドエンジニアrails歴:2 ~ 3ヶ月
![Page 3: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/3.jpg)
before_actionでインスタンス変数をセットしているコードを
見かけることがある
![Page 4: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/4.jpg)
class UserController < ApplicationController before_action :set_user def index() //何らかの処理 @user.execute end private def set_user @user = User.findby(id: 100) endend
![Page 5: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/5.jpg)
before_action で変数をセットする実装が好きではない
自分ならこう書く
![Page 6: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/6.jpg)
class UserController < ApplicationController def index() @user = find_user(100) @user.execute end private def find_user(id) User.findby(id: id) endend
![Page 7: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/7.jpg)
before_actionでの変数セットをやめてaction側でprivateな関数を呼び出す
![Page 8: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/8.jpg)
サーバサイドでjsonを返す場合はインスタンス変数すら不要になるので、
user変数のスコープを狭くできる
![Page 9: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/9.jpg)
class UserController < ApplicationController def index() user = find_user(100) user.execute render json: user end private def find_user(id) User.findby(id: id) endend
![Page 10: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/10.jpg)
なぜ、こういった実装をするのか?
![Page 11: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/11.jpg)
before_actionが連続した場合の変数書き換えを防ぐ
![Page 12: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/12.jpg)
class UserController < ApplicationController // それぞれで同じ変数を書き換えているかも // before_action が増えたら、 // 実行順と変数の状態を考慮する必要がある before_action :aaa before_action :bbb, only: ['index', 'detail'] before_action :ccc, except: ['index', 'detail']end
![Page 13: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/13.jpg)
before_actionは戻り値を取れないので、Controller内のインスタンス変数に対して副作用を与える実装になってしまいがちaction内で明示的に呼ぶことによって
参照透過な実装になる
![Page 14: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/14.jpg)
データの読み込みも処理の一部action内で明示することによって、処理の流れがaction内で完結する
![Page 15: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/15.jpg)
before_actionは何をするのか?
![Page 16: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/16.jpg)
actionを実行するかどうかのバリデーションに利用する
例:権限チェック
可能な限りbefore_action同士で依存関係を
持たないようにした方がいい
![Page 17: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/17.jpg)
人によってはDRYに反していると思うかもしれないが、action内の関数呼び出しは重複だろうか?
変数のスコープを限定する方が大事だと思う
![Page 18: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/18.jpg)
同じ考えを持つ方々http://craftingruby.com/posts/2015/05/31/dont-use-before-action-to-load-data.htmlhttp://blog.ragnarson.com/2015/09/30/problems-with-typical-rails-controllers-and-before-actions.htmlhttp://blog.thefrontiergroup.com.au/2014/02/before_action
_an_anti_pattern/
![Page 19: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/19.jpg)
「Best Practice」らしいが、コメント欄を確認すると面白い
http://rails-bestpractices.com/posts/2010/07/24/use-
before_filter/
![Page 20: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/20.jpg)
今回の内容はrailsというよりも変数のスコープや副作用の話なので、
実はrails関係ない
![Page 21: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/21.jpg)
おわり
![Page 22: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/22.jpg)
ここから発表後の追記です
![Page 23: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/23.jpg)
発表時間が余ったので
before_actionで変数をセットしている人いますか?
と聞いたところ・・・・
![Page 24: Controllerのbefore_actionにおける インスタンス変数セットについて](https://reader033.vdocuments.net/reader033/viewer/2022052117/587de46c1a28abaf6b8b6217/html5/thumbnails/24.jpg)
25人中2,3人がセットしているとのこと
before_actionで変数セットするのって少数派なのかな・・・
だとしたら、わざわざ取り上げるテーマでもなかった
かもしれない・・・