0
0

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 1 year has passed since last update.

コントローラの内容をレンダリングする

Posted at

railsチュートリアルの説明の大まかな流れ

まずユーザーに送信すべきレスポンスの内容を決定し、次にユーザーへのレスポンスを作成する適切なメソッドを呼び出します。 レスポンス画面を完全なビューで作成すると、Railsはそのビューをレイアウトでラップして、場合によってはパーシャルビューもそこに追加します。本ガイドではこれらの方法をひととおり紹介します。

気づき

レイアウトでラップするという意味がわからない。
包むというらしい。

コントローラ名のビューを探してレンダリングする。

「コントローラのアクションの末尾で明示的にレンダリングが指示されていない場合は、コントローラが利用可能なビューのパスからアクション名.html.erbというビューテンプレートを探し、それを使って自動的にレンダリングする」

renderメソッド

ほとんどの場合、アプリケーションがブラウザで表示するコンテンツのレンダリングには
ActionController::Base#renderメソッドが使われます。

できること

特定のテンプレート、ファイル、インラインコードを指定してレンダリングすることも、何も出力しないようにすることもできます。テキスト、JSON、XMLをレンダリングすることもできます。

他にも

レスポンスをレンダリングするときにContent-TypeヘッダーやHTTPステータスを指定することもできます。

別コントローラの配下のテンプレートをレンダリングする。

あるコントローラのアクションから、まったく別のコントローラの配下にあるテンプレートを利用してレンダリングすることは可能です。これもrenderメソッドでできます。
...
renderメソッドにはapp/viewsを起点とするフルパスを渡せるので、レンダリングするテンプレートをフルパスで指定します。

renderで:inlineを指定する

renderメソッドを呼び出すときに:inlineオプションでERBを渡すと、ビューをまったく使わずにレンダリングできます。以下の書き方は完全に有効です。

render inline: "<% products.each do |p| %><p><%= p.name %></p><% end %>"

注意点

このオプションを実際に使う意味はめったにありません。コントローラのコードにERBを直接書き込むと、RailsのMVC指向が損なわれ、開発者がプロジェクトのロジックを追いかけることが難しくなってしまいます。ERBビューをお使いください。

テキストをレンダリングする

renderメソッドで:plainオプションを指定すると、平文テキストをマークアップせずにブラウザに送信できます。

render plain: "OK"

render_to_stringメソッド

render呼び出しの正確な結果をブラウザを使わずに調べたい場合は、render_to_stringを利用できます。このメソッドの振る舞いは、レンダリング結果をブラウザに返さずに文字列を返す点を除けば、renderと完全に同じです。

気づき

いつか使えそうかな。

redirect_toメソッドを使う。

renderはレスポンスを構成するときに使うビュー(または他のアセット)を指定しますが、redirect_toメソッドは、この点においてrenderメソッドと根本的に異なります
redirect_toメソッドは、別のURLにリクエストを再送信するようブラウザに指示します。

たとえば以下の呼び出しを行なうと、アプリケーションで現在どのページが表示されていても、写真のindexページにリダイレクトされます。

redirect_to photos_url

redirect_toを実行すると、コードはそこで実行を停止して、ブラウザからの次のリクエストを待ちます(これは通常のスタンバイ状態です)。その直後、redirect_toでブラウザに送信したHTTPステータスコード302に従って、ブラウザは別のURLへのリクエストをサーバーに送信し、サーバーはそのリクエストを改めて処理します。

def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    render action: "index"
  end
end

上のフォームのコードでは、````@bookインスタンス変数がnilの場合に問題が生じる可能性があります。render :actionを実行しても、対象となるアクションのコードは実行されないことを思い出しましょう。つまりindexビューでおそらく必要となる@booksインスタンス変数には何も設定されず、空の蔵書リストが表示```されてしまいます。 これを修正する方法の1つは、```renderを以下のようにredirect_toに変更```することです。

def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    redirect_to action: :index
  end
end

上のコードでは、ブラウザから改めてindexページにリクエストが送信されるので、indexメソッドのコードが正常に実行されます。

上のコードで惜しい点は、ブラウザとの通信が1往復必要になることです。ブラウザから/books/1に対してshowアクションが呼び出され、本が1冊もないことをコントローラが検出すると、コントローラはブラウザにステータスコード302(リダイレクト)レスポンスを返し、/books/に再度アクセスするようブラウザに指示します。ブラウザはこの指示に沿って、コントローラのindexアクションを呼び出すリクエストを改めてサーバーに送信します。コントローラはこのリクエストを受け取って、データベースからすべての蔵書リストを取り出し、indexテンプレートをレンダリングして結果をブラウザに送り返すと、ブラウザで蔵書リストが表示されます。

気づき

renderとredirect_toの違いがわからなかった。
もっと勉強をしなければならない。
時間が来たのでまた。
とりあえずrenderメソッドを使い。
もう一度疑問点を洗い出す。

出典

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?