Controllerに記述された同様の処理の省略(Ruby on Rails)
以下のように記述されたコントローラーのコードを可読性を向上させるために、before_actionを用いて省略します。
※一例なのでアクションやコードは一部省略しています。
app/controllers/items_controller.rb
class ItemsController < ApplicationController
def index
@items = Item.all.order('created_at DESC')
end
def show
@item = Item.find(params[:id])
end
def edit
@item = Item.find(params[:id])
unless @item.user.id == current_user.id
redirect_to action: :index
end
end
def update
@item = Item.find(params[:id])
@item.update
end
end
上記のコードを見てみると、@item = Item.find(params[:id])という記述が随所に見られます。このように記述しても動作には問題ありませんが、コードの可読性を上げたい場合、これを効率良く記述したいです。そのためにはbefore_actionを用います。
before_actionは、コントローラーで定義されたアクションが実行される前にbefore_actionに定義した処理を全て共通のものとして実行することができます。さらにonlyやexceptといったオプションを付与することで、指定したアクションに対してbefore_actionを実行することができます。それでは、before_actionを用いてまとめたコードを見てみましょう。
※一例なのでアクションやコードは一部省略しています。
app/controllers/items_controller.rb
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update]
before_action :user_match, only: [:edit, :update]
def index
@items = Item.all.order('created_at DESC')
end
def show
end
def edit
end
def update
@item.update
end
private
def set_item
@item = Item.find(params[:id])
end
def user_match
unless @item.user.id == current_user.id
redirect_to action: :index
end
end
end
上記のコードの、before_actionの記述の見方は以下の通りです。
before_action :処理を行いたいメソッドの名前, only: [:限定するアクションの名前]
そして、private以下に一つの共通する処理として書き出してまとめています。このようにコードを省略することにより読みやすくなりました。
またuser_matchメソッドに対してeditアクション以外にupdateアクションを指定し、before_actionの処理としてまとめている理由としては第三者がリクエストを改ざんし、editアクションの編集ページを経由しないでupdateアクションを動かすことができる可能性があるからです。deviseによるユーザー管理機能をアプリケーションに実装しているのであれば、セキュリティ対策として以下のようなeditアクションに記述された条件分岐のコードをupdateアクションにも付け加える必要があります。
unless @item.user.id == current_user.id
redirect_to action: :index
end
そのためbefore_actionのメソッドとしてまとめています。
この記事が気に入ったらサポートをしてみませんか?