Ruby on Railsのredirect_toは、ブラウザに別のURLへのリダイレクトを指示するメソッドです。フォーム送信後の画面遷移や、認証が必要なページへの未ログインユーザーの誘導など、様々な場面で使用されます。この記事では、redirect_toの基本的な使い方からフラッシュメッセージの組み合わせまで解説します。
基本的な使い方
redirect_toに遷移先のURLまたはパスヘルパーを指定すると、ブラウザに302リダイレクトが返されます。
class TestController < ApplicationController
def index
redirect_to "/test2"
# http://127.0.0.1:3000/test2にリダイレクトされる
end
end上記のコードでは、/にアクセスすると自動的に/test2に転送されます。ブラウザのURLバーも遷移先のURLに変わります。
パスヘルパーを使ったリダイレクト
URLを文字列で直接指定するよりも、Railsのパスヘルパーを使うのが推奨されます。ルーティングの変更に強く、タイプミスも防げます。
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
redirect_to post_path(@post) # /posts/:idにリダイレクト
else
render :new
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to posts_path # /postsにリダイレクト
end
endpost_path(@post)は/posts/1のようなURLを生成し、posts_pathは/postsを生成します。モデルオブジェクトを直接渡すこともできます。
# 以下は同じ意味
redirect_to post_path(@post)
redirect_to @postフラッシュメッセージ付きリダイレクト
リダイレクト先のページにメッセージを表示したい場合は、noticeやalertオプションを使います。
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: "投稿を作成しました"
else
render :new
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to posts_path, alert: "投稿を削除しました"
end
endフラッシュメッセージはリダイレクト先で1回だけ表示され、次のリクエストでは自動的に消えます。レイアウトファイルに以下のようにフラッシュ表示を追加しておきます。
<% if flash[:notice] %>
<div class="alert alert-success"><%= flash[:notice] %></div>
<% end %>
<% if flash[:alert] %>
<div class="alert alert-danger"><%= flash[:alert] %></div>
<% end %>
<%= yield %>redirect_toとrenderの違い
redirect_toとrenderは混同しやすいですが、動作が根本的に異なります。
| 機能 | redirect_to | render |
|---|---|---|
| 動作 | ブラウザに新しいリクエストを送らせる | 現在のリクエスト内でビューを表示 |
| URL | 変わる | 変わらない |
| インスタンス変数 | リセットされる | 保持される |
| 主な用途 | 保存成功後の画面遷移 | バリデーションエラー時のフォーム再表示 |
フォームのバリデーションエラー時にredirect_toを使うと、エラー情報(@post.errors)が失われます。エラーフォームを再表示する場合は必ずrenderを使いましょう。
条件付きリダイレクト
before_actionと組み合わせて、認証チェックやアクセス権限の確認にリダイレクトを使うのが一般的です。
class ApplicationController < ActionController::Base
private
def require_login
unless current_user
redirect_to login_path, alert: "ログインが必要です"
end
end
endredirect_toの後にもコードは実行されます。処理を確実に止めたい場合はredirect_to ... and returnと記述してください。
まとめ
redirect_toはブラウザに新しいリクエストを送らせてページ遷移する- パスヘルパー(
posts_path等)を使うのが推奨される notice:やalert:でフラッシュメッセージを付与できるredirect_toはURL変更あり、renderはURL変更なし- バリデーションエラー時は
render、保存成功時はredirect_toを使う redirect_to後に処理を止めるにはand returnを付ける