LoginSignup
1
2

More than 3 years have passed since last update.

before_actionとは?

Posted at

はじめに

今回はアプリ開発を通じてbefore_actionとはどういう働きをしているのか学習していきます。

before_actonとは?

railsのコントローラーのアクションを実行する前に処理を行いたいときや、同じ記述の処理をまとめたい時に使います。

基本的な書き方は以下です

tests_controller.rb
   before_action :処理させたいメソッド名

この場合だと、同じコントローラーに定義されている各メソッドの実行の前に、指定したメソッドによる処理が行われます。

もしくはresourcesメソッドと同じようにonlyやexceptなどでアクションの限定をすることもできます。

tests_controller.rb
before_action :処理させたいメソッド名, only: [:アクション1,:アクション2]

この場合はアクション1と2が実行される前にのみ、指定した「処理したいメソッド」が実行されます。

実際の使用例

categories_controller.rb
class CategoriesController < ApplicationController
  def index
    @categorys = Category.all
    @category = Category.new
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      redirect_to categories_path
    else
      @categorys = Category.all
      render :index
    end
  end

  def edit
    @category = Category.find(params[:id])     ⇦処理が被っている
  end

  def update
    @category = Category.find(params[:id])      ⇦処理が被っている
    if @category.update(category_params)
      redirect_to categories_path
    else
      render :edit
    end
  end

  def search
    @categorys = Category.where(is_valid: true)
    @category = Category.find(params[:id])     ⇦処理が被っている
    @q = @category.notes.all.ransack(params[:q])
    @notes = @q.result(distinct: true)
    @title = @category.name
    render 'notes/index'
  end


  private

  def category_params
    params.require(:category).permit(:name, :is_valid)
  end
end

みてもらうと分かりますが、editとupdateとsearchにおいて記述が被っています

そのため、上記のコードをリファクタリングし、

categories_controller.rb
class CategoriesController < ApplicationController
  before_action :set_category, only: [:edit, :update, :search]    ⇦追加


  def index
    @categorys = Category.all
    @category = Category.new
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      redirect_to categories_path
    else
      @categorys = Category.all
      render :index
    end
  end

  def edit
  end

  def update
    if @category.update(category_params)
      redirect_to categories_path
    else
      render :edit
    end
  end

  def search
    @categorys = Category.where(is_valid: true)
    @q = @category.notes.all.ransack(params[:q])
    @notes = @q.result(distinct: true)
    @title = @category.name
    render 'notes/index'
  end


  private

  def category_params
    params.require(:category).permit(:name, :is_valid)
  end

  def set_category
    @category = Category.find(params[:id])       ⇦共通の処理をまとめている
  end
end

共通の処理をset_categoryというメソッドでまとめ、updateアクションとeditアクションとsearchアクションの実行の際にbefore_actionで呼び出しています。

authenticate_user!

before_action :authenticate_user!

上記はdeviseを導入した際に使えるようになるメソッドである「authenticate_user!」があります。ログインしていない場合はログイン画面に遷移させるメソッドです。

よく、Amazonなどの通販サイトなどを使用していると分かりますが、商品の閲覧はログインしていなくても出来るけど、購入に進むとログインを求められますよね。

このように何らかのアクションを実行する前に行なって欲しい共通の処理をbefore_actionでは指定します。

最後に

今回はbefore_actionがどういう働きをしているのか何となくわかりました。
参考になれば幸いです。
他にもわかったことがあれば随時更新していきます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2