#before_actionとは
railsのコントローラーのアクションを実行する前に処理を行いたいときや、同じ記述の処理をまとめたい時に使います。
基本的な書き方は以下です
before_action :処理させたいメソッド名
この場合だと、同じコントローラーに定義されている各メソッドの実行の前に、指定したメソッドによる処理が行われます。
もしくはresourcesメソッドと同じようにonlyやexceptなどでアクションの限定をすることもできます。
before_action :処理させたいメソッド名, only: [:アクション1,:アクション2]
この場合はアクション1と2が実行される前にのみ、指定した「処理したいメソッド」が実行されます。
#使用例
コントローラーに下記の記述があったとします。
class TweetsController < ApplicationController
def index
@tweets = Tweet.all
end
def new
@tweet = Tweet.new
end
def create
Tweet.create(tweet_params)
end
def destroy
tweet = Tweet.find(params[:id])
tweet.destroy
end
def edit
@tweet = Tweet.find(params[:id]) ←処理が被ってる
end
def update
tweet = Tweet.find(params[:id])
tweet.update(tweet_params)
end
def show
@tweet = Tweet.find(params[:id]) ←処理が被ってる
end
private
def tweet_params
params.require(:tweet).permit(:name,:text)
end
end
みてもらうと分かりますが、editとshowにおいて記述が被っています
そのため、上記のコードをリファクタリングし、
class TweetsController < ApplicationController
before_action :set_tweet, only: [:edit, :show]
def index
@tweets = Tweet.all
end
def new
@tweet = Tweet.new
end
def create
Tweet.create(tweet_params)
end
def destroy
tweet = Tweet.find(params[:id])
tweet.destroy
end
def edit
end
def update
tweet = Tweet.find(params[:id])
tweet.update(tweet_params)
end
def show
end
private
def tweet_params
params.require(:tweet).permit(:name,:text)
end
def set_tweet ←共通の処理をまとめている
@tweet = Tweet.find(params[:id])
end
end
共通の処理をset_tweetというメソッドでまとめ、showアクションとeditアクションの実行の際にbefore_actionで呼び出しています。
#もっと分かりやすいイメージ
before_action :authenticate_user!
上記はdeviseを導入した際に使えるようになるメソッドである「authenticate_user!」を指定しています。ログインしていない場合はログイン画面に遷移させるメソッドです。
よく、Amazonなどの通販サイトなどを使用していると分かりますが、商品の閲覧はログインしていなくても出来るけど、購入に進むとログインを求められますよね。
このように何らかのアクションを実行する前に行なって欲しい共通の処理をbefore_actionでは指定します。