基本

Ruby on Railsで指定したビューを表示させる(render)

Ruby on Railsでは、コントローラーのアクション名と同じ名前のビューファイルが自動的にレンダリングされます。しかし、renderメソッドを使うことで、デフォルトとは異なるビューテンプレートを明示的に指定して表示することができます。この記事では、renderメソッドの様々な使い方と実践的な活用方法を解説します。

基本的な使い方

Railsでは通常、アクション名に対応するビューが自動的に表示されます。例えば、indexアクションはindex.html.erbを表示します。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
    # 自動的にapp/views/posts/index.html.erbが表示される
  end
end

この自動的なビューの選択は「暗黙のレンダリング」と呼ばれます。Railsがアクション名からビューファイルのパスを推測して表示してくれるため、多くの場合はrenderを明示的に書く必要はありません。

別のビューを表示する

同じコントローラーのビューディレクトリ内にある別のビューを指定して表示するには、renderにビュー名を文字列で渡します。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
    render "list"
    # app/views/posts/list.html.erbが表示される
  end
end

上記の例では、indexアクションがデフォルトのindex.html.erbではなく、list.html.erbを表示します。拡張子(.html.erb)は省略して指定します。

シンボルを使って指定することもできます。

Ruby
render :list
# render "list" と同じ

別のフォルダのビューを表示する

異なるコントローラーのビューディレクトリにあるテンプレートを表示することも可能です。app/views/からの相対パスを指定します。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @user = current_user
    render "users/dashboard"
    # app/views/users/dashboard.html.erbが表示される
  end
end

この機能は、複数のコントローラーで同じビューテンプレートを共有したい場合に便利です。例えば、管理者用と一般ユーザー用のコントローラーで同じダッシュボードビューを使いたい場合などに活用できます。

renderのオプション

renderメソッドには様々なオプションがあり、テキストやJSON、ステータスコードなどを返すことができます。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  # プレーンテキストを返す
  def text_example
    render plain: "Hello, World!"
  end

  # JSONを返す
  def json_example
    render json: { message: "成功", posts: @posts }
  end

  # ステータスコードを指定する
  def not_found
    render file: "#{Rails.root}/public/404.html",
           status: :not_found,
           layout: false
  end

  # HTMLを直接返す
  def inline_example
    render html: "<h1>直接HTMLを返す</h1>".html_safe
  end

  # レイアウトを変更する
  def admin_page
    render layout: "admin"
    # app/views/layouts/admin.html.erbが使用される
  end
end

render json:はAPIエンドポイントを実装する際によく使います。status:オプションでHTTPステータスコードを指定でき、シンボル(:not_found:ok:createdなど)で記述できます。

createやupdateでの活用

renderの最も一般的な使い方の一つが、バリデーションエラー時にフォームを再表示する場面です。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to @post, notice: "投稿を作成しました"
    else
      render :new, status: :unprocessable_entity
      # エラーメッセージ付きでフォームを再表示
    end
  end

  def update
    @post = Post.find(params[:id])
    if @post.update(post_params)
      redirect_to @post, notice: "投稿を更新しました"
    else
      render :edit, status: :unprocessable_entity
    end
  end
end

保存に失敗した場合、redirect_toではなくrenderを使います。renderはHTTPリダイレクトを行わないため、@postに格納されたバリデーションエラー情報がそのままビューで使用でき、ユーザーにエラー内容を表示できます。

ポイント

renderredirect_toの違いを理解することが重要です。renderは現在のリクエスト内で別のビューを表示するだけで、URLは変わりません。redirect_toはブラウザに新しいリクエストを送らせるため、URLが変わります。

注意

1つのアクション内でrenderを複数回呼ぶとエラーになります(AbstractController::DoubleRenderError)。条件分岐でrenderredirect_toを使い分ける場合は、必ずreturnをつけるか、if/elseで排他的に記述してください。

まとめ

  • Railsはアクション名に対応するビューを自動的にレンダリングする(暗黙のレンダリング)
  • render "ビュー名"で同じフォルダ内の別ビューを表示できる
  • render "フォルダ名/ビュー名"で別フォルダのビューを表示できる
  • render plain:render json:でテキストやJSONを直接返せる
  • バリデーションエラー時はredirect_toではなくrenderでフォームを再表示する
  • 1つのアクション内でrenderを複数回呼ぶとエラーになるので注意