📚
【Rails】サンプルで見るrenderとridirect_toの違い
サンプルアプリの作成
まずはRailsのscaffoldを使い、サンプルアプリを作成します。
rails new sample_app
cd sample_app
rails g scaffold User name:string detail:text
rails db:migrate
ユーザー一覧ページ
ユーザー追加ページ
バリデーションを設定します。
Nameが空欄の場合と、Detailの文字数が50を超える場合にエラーが出るようにします。
user.rb
class User < ApplicationRecord
validates :name, presence: true
validates :detail, length: { maximum: 50 }
end
これで準備が整いました。
それでは、わかりやすいようにバリデーションエラーを起こして、
renderとredirect_toの動きを見ていきましょう。
users_controller_rb
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to user_url(@user), notice: "User was successfully created." }
format.json { render :show, status: :created, location: @user }
else
format.html { render :new, status: :unprocessable_entity }
# format.html { redirect_to new_user_path }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
New userのページで「Create user」をクリックした際に、バリデーションに引っ掛かると上記コードのelseの処理が実行されます。
Name
山田太郎
Detail
サンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプルサンプル
とします。
まずは、renderだとどうなるか見ていきましょう。
エラー文が出力されています。
NameとDetailはそのまま残っています。
次に、ridirect_toだとどうなるか見ていきましょう。
users_controller_rb
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to user_url(@user), notice: "User was successfully created." }
format.json { render :show, status: :created, location: @user }
else
# format.html { render :new, status: :unprocessable_entity }
format.html { redirect_to new_user_path }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
Create userをクリックしたら、入力してたものがなくなってしまいました。
まとめ
renderは、現在のコントローラ(または他の指定されたコントローラ)から指定されたビューに直接遷移します。新しいリクエストは生成されません。
redirect_toは、指定されたURLに新しいHTTPリクエストを発行し、そのURLが関連付けられたルーティング設定に基づいて新しいコントローラアクションを実行します。そして、そのコントローラアクションは新しいビューを表示します。
- render : controller → view
- redirect_to : controller → URL → route → controller → view
Discussion