0
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【before_actionって?】Ruby on Rails初心者に向けて

Last updated at Posted at 2020-08-21

どうも!
三町哲平です。
MacBook Airを触り出して2週間、扱いにもだいぶ慣れてきました。

さて今回は、
Ruby on Rails5 学習コース VIII | プログラミングの入門なら基礎から学べるProgate[プロゲート]
で勉強中にこれなんだったっけ?というソースコードを見つけました。

users_controller.rb
class UsersController < ApplicationController
  before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
  before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
  before_action :ensure_correct_user, {only: [:edit, :update]}
...
...
...
end

今回はこのソースコードを深掘りしていきます。

users_controller.rb
class UsersController < ApplicationControlle

まずソースコードの上記部分からの説明で、これを一言で説明すると「classの継承」をしています。

継承とは?

継承は、既存のクラスから、新しく作ったクラスに「変数定義」や「メソッド」などを引き継ぐことです。継承される既存のクラスを「スーパークラス(親クラス)」、継承した新しく作ったクラスを「サブクラス」といいます。
引用元:オブジェクト指向「継承」とは?わかりやすく解説してみた | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

つまり今回の場合、
__ApplicationControllerクラス__を__UsersControllerクラス__へ継承しているということになる訳です。

ApplicationControllerクラスとは?

異なるコントローラ間で共通に使用するメソッドは, ApplicationControllerクラスで定義します。各コントローラは, 原則としてApplicationControllerを継承しているのでここ(app/controllers/application.rb)で定義すればどのコントローラでも使えます。
引用元:Railsで共通メソッドの作り方 - 線路は続くよどこまでも。

Ruby on Rails5の学習をしていたのですが、これはRailsのControllerという機能に関係するのですが、Controllerとは、ルーティングに関わる機能です。

before_actionとは?

アクションを実行する前に処理を実行したい場合に使用します。

users_controller.rbを実行する前に下記の内容を実行することになります。

:authenticate_user, {only: [:index, :show, :edit, :update]}
:forbid_login_user, {only: [:new, :create, :login_form, :login]}
:ensure_correct_user, {only: [:edit, :update]}

ちなみに、__:authenticate_user__の部分は、メソッドにあたります。

そして、残りのソースコードは、下記の部分ということになりますが、

{only: [:index, :show, :edit, :update]}
{only: [:new, :create, :login_form, :login]}
{only: [:edit, :update]}

まず、__only:__の部分ですが、これはオプションにあたります。
before_actionには様々なオプションを付けることができる訳ですね。

onlyオプションとは?

特定のアクションのときだけbefore_actionを使いたい場合はonlyを使います。

つまり、

  • authenticate_userメソッド → index, show, edit, updateアクションのみで使用可
  • forbid_login_userメソッド → new, create, login_form, loginアクションのみで使用可
  • ensure_correct_user → edit, updateアクションのみで使用可

このような意味だった訳ですね。

それを踏まえた上で、users_controller.rbの隠れていた部分も含め表示してみましょう!

users_controller.rb
class UsersController < ApplicationController
  before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
  before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
  before_action :ensure_correct_user, {only: [:edit, :update]}
...
...
...
end

users_controller.rb
class UsersController < ApplicationController
  before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
  before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
  before_action :ensure_correct_user, {only: [:edit, :update]}
  
  def index
    @users = User.all
  end
  
  def show
    @user = User.find_by(id: params[:id])
  end
  
  def new
    @user = User.new
  end
  
  def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      image_name: "default_user.jpg",
      password: params[:password]
    )
    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "ユーザー登録が完了しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end
  
  def edit
    @user = User.find_by(id: params[:id])
  end
  
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    
    if params[:image]
      @user.image_name = "#{@user.id}.jpg"
      image = params[:image]
      File.binwrite("public/user_images/#{@user.image_name}", image.read)
    end
    
    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/edit")
    end
  end
  
  def login_form
  end
  
  def login
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
      session[:user_id] = @user.id
      flash[:notice] = "ログインしました"
      redirect_to("/posts/index")
    else
      @error_message = "メールアドレスまたはパスワードが間違っています"
      @email = params[:email]
      @password = params[:password]
      render("users/login_form")
    end
  end
  
  def logout
    session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end
  
  def ensure_correct_user
    if @current_user.id != params[:id].to_i
      flash[:notice] = "権限がありません"
      redirect_to("/posts/index")
    end
  end
  
end

引用元:Ruby on Rails5 学習コース VIII | プログラミングの入門なら基礎から学べるProgate[プロゲート]

該当するアクションが全て含まれていることが確認できます!

さいごに

before_actionのonlyオプション意外のオプションも知りたいという方は、こちらの参考サイトもご参照ください。
[【Rails】before_actionの使い方を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト]
(https://pikawaka.com/rails/before_action#before_action%E3%81%AE%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3)

0
5
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
0
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?