LoginSignup
9
6

More than 3 years have passed since last update.

【Rails】 controller内で共通の処理をメソッド化してbefore_actionで呼び出す

Posted at

環境

rails 5.2.3
ruby 2.5.1

概要

コントローラー内で共通の処理を書いていたら、メンターにメソッド化しましょうと言われたので、脱・初心者を目指し、備忘録。

メンターレビュー前

hogehoge_controller.rb
class hogehogeController < ApplicationController

  def new
    @user = User.find(params[:user_id])
    @evaluation_all = Evaluation.group(:seller_id).size[@user.id]
    @evaluation = Evaluation.new
  end


  def create
    @user = User.find(params[:user_id])
    @evaluation = Evaluation.new(evaluation_params)
    if @evaluation.save
      redirect_to introduction_user_path(@user.id), notice: "評価が送信されました"
    else
      redirect_to introduction_user_path, notice: "評価が正常に送信できませんでした。もう一度行ってください。"
    end
  end

  private

  def user_params
    params.require(:user)
  end

  def evaluation_params
    params.require(:evaluation).permit(:rating, :comment).merge(buyer_id: current_user.id, seller_id: @user.id)
  end
end

指摘されたのはこの部分。

@user = User.find(params[:user_id])

同じ記述が2回出てきていますね。
この@userの処理は共通のものなので、分けましょう、と言われたわけです。

またこの処理は外部から呼び込まれる必要はないので、private以下に追記します。

private
  def set_user
    @user = User.find(params[:user_id])
  end

こうすることで、呼び出しがクラス内部に限定されるんですね。

privateについてはこちらの記事が勉強になりました。ありがとうございます。
Ruby の private と protected 。歴史と使い分け

さて、あとは各メソッドが実行される時に呼び出されると善きですね。

そんな時は before_actionを使います。

class EvaluationsController < ApplicationController

  before_action :set_user, only: [:new, :create]

  def new
    hogehoge...

before_action [メソッド名],[おぷしょん]

onlyは、どのメソッドが呼ばれた時にbefore_actionを実行するのかを示し、
expect は、指定したメソッドが呼ばれた時は実行しません。

今回は、newとcreateの実行前にやってほしい処理ですからこうします。

 before_action :set_user, only: [:new, :create]

メンターレビュー後

...というわけで直したのがこちら

hogehoge_controller.rb
class EvaluationsController < ApplicationController

  before_action :set_user, only: [:new, :create]

  def new
    @evaluation_all = Evaluation.group(:seller_id).size[@user.id]
    @evaluation = Evaluation.new
  end


  def create
    @evaluation = Evaluation.new(evaluation_params)
    if @evaluation.save
      redirect_to introduction_user_path(@user.id), notice: "評価が送信されました"
    else
      redirect_to introduction_user_path, notice: "評価が正常に送信できませんでした。もう一度行ってください。"
    end
  end

  private

  def set_user
    @user = User.find(params[:user_id])
  end

  def user_params
    params.require(:user)
  end

  def evaluation_params
    params.require(:evaluation).permit(:rating, :comment).merge(buyer_id: current_user.id, seller_id: @user.id)
  end
end
9
6
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
9
6