Railsを習い始めてから、当初覚えた render :hoge and return
で Double Renderrer 例外を出さない書き方をずっと使い続けていたが、PRのレビューで return render :hoge
が簡潔で読みやすいのでは無いかという指摘をもらって、ふと気になったので挙動を調べてみる
ActionController::Base
RailsのControllerで必ず継承される親クラスから
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/base.rb#L159
コメント行で、「処理を中断させるなら and return
を使いましょう」と書いてあるが、redirect_toの場合の例しかない
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/base.rb#L206
renderに関するクラスをincludeするために列挙されている
AbstractController::Rendering
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/rendering.rb
render の処理は書いてあるが、Controller#Actionの返り値を判断するクラスではなさそう
ActionController::Baseに戻る
またActionController::Base
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/base.rb#L239
Callback関連がありそうなので見てみる
ActionController::Callback
around_actionあたりに期待したが、返り値に関する処理は特になかった
ActionController::Baseに戻る
またまたActionController::Base
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/base.rb#L166
ActionController::BaseはMetalを継承している
ActionController::Metal
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal.rb#L191
processメソッドが怪しい
Metalクラスにはprocessメソッドが実装されていないので、親クラスを探る
AbstractController::Base
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/base.rb
このクラスは継承がないのでActionControllerの大元っぽい
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/base.rb#L127
processメソッド発見
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/base.rb#L136
process_actionが怪しい
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/base.rb#L195
send_actionを呼んでいる
https://github.com/rails/rails/blob/master/actionpack/lib/abstract_controller/base.rb#L204
sendをsend_actionにaliasしているので、send_actionはsend
ってことはsend_actionの返り値を判断して処理を行なっているか確認すればいい
今までの流れを遡る
- AbstractController::Base#process_actionはsend_actionをそのまま返している
- AbstractController::Base#process は process_actionをそのまま返している
- ActionController::Metal#dispatch は process を呼んで、返り値を求めていない
まとめ
render の返り値に応じたActionControllerの挙動は特に定義されていないことがわかった
render :hoge and return
でも return render :hoge
でも挙動に変化はない
ただ、render
した結果を return
するように見えるので、コードレビューをする際に挙動に変化がないことのコンセンサスが必要に感じた