Callbackメソッドの「only」「except」の使い分け(Rails)
【結論】
・Controllerのコールバックメソッドは、only
とexcept
で実行するアクションを指定できるが、適切に使い分けないと、バグ発生の要因となり得る
・基本的にonly
を使用する。指定するアクションが増えて、追加するアクションが無くなったらexcept
に置き換える。
・権限の制御など、アクションの実行に制限を設けるコールバックであれば、始めからexcept
を利用する。
【目次】
【本題】
Callbackメソッドのオプションの使い分け
before_action
やafter_action
といったControllerのCallbackメソッドは、オプションでコールバックを実行させるアクションを指定することができます。
only
では、指定したアクションだけ、コールバックが実行されます。
except
では、指定したアクション以外で、コールバックが実行されます。
class PostsController < ApplicationController before_action :authenticate_user!, :except=>[:show] before_action :set_post, only: [:show, :edit] def show @post_comments = PostComment.where(post_id: params[:id]) end def edit end private def set_post @post = Post.find(params[:id]) end end
これにより、共通の処理を一つの記述にまとめることが出来て、コードの見通しが良くなります。
暗黙的に実行されていることによる弊害
しかしコールバックの処理は、アクション内では明示されていない為、存在を見落としてしまう可能性もあります。
そうなると、アクションを指定し忘れてしまい、それによって意図せぬ挙動が発生してしまうリスクがあります。
例えば、本来は管理者しかアクセスできないページ(アクション)に、一般のユーザーもアクセスできてしまうという事象です。
なので、アクションの指定方法も、それらのリスクを最小限に留めるように設定を行う必要があります。
基本的にonly
を使用する
except
だと明示的に指定したアクション以外にコールバックが適用されます。
なので、アクションを追加した際にコールバックを見落としてしまうと、本来適用したくなかったコールバックが適用されてしまうことになってしまいます。
only
を使用すれば、実行するアクションを明示的に指定できるので、意図せぬコールバックが適用される事態は防げます。
しかし、適用するアクションが増えるほど記述量が多くなり、見通しが悪くなることで、どのアクションにコールバックが適用されているのか見辛くなります。
そこで、except
で書いた方が記述量が減るのであれば、except
に置き換えましょう。
但し、今後もアクションを追加する予定があるのであれば、except
に置き換えることで先ほどの問題が発生する可能性もあるので、アクションの追加がひと段落してからの方が良いでしょう。
制限を設けるコールバックはexcept
を使用する
基本的にはonly
を使用しますが、except
を使用した方が良いと思われる場合もあります。
それはコールバックによって、アクションの実行に制限を設ける場合です。
例えば「管理者のみアクセスできるようにしたい」といった権限の制御などです(そもそもコールバックで処理すべきでは無いかもしれないですが・・・)
これをonly
で設定してしまうと、もしコールバックの設定を見逃した場合、一般のユーザーでも管理者専用のアクションが実行できてしまいます。
except
を使用すれば、追加したアクションに直ぐコールバックが適用されるので、こういった事態を防ぐことが可能です。