render
Railsを学習していてrenderを使うことは多々あります。
なんとなく使っていて理解が浅いと感じたので、一度しっかりおさらいして
renderを使いこなせるようにしたい、と思いアウトプットすることに。
renderを使う場面
renderを使う場面は大きく分けて2種類あります。
- controllerで使用
- viewで使用
controllerで使用
controllerでは、renderを使うことで指定したviewファイルを呼び出します。
# users_controller def create @user = User.new(user_params) if @user.save redirect_to login_path else render :new end end private def user_params params.require(:user).permit(:name, :email) end
このコードでは新規ユーザーの作成が成功したときはログインページへ遷移、
失敗したときはusers/new.html.erbを呼び出す、という流れです。
redirect_toは引数で指定したpathをサーバーにリクエストし、レスポンスを表示します。
renderはアクションは経由せず直接users/new.html.erbを表示します。
viewで使用
viewではrenderを使うことで部分テンプレートを呼び出します。
posts/new.html.erbとposts/edit.html.erbのように、新規投稿ページと投稿編集ページがあるとします。
投稿のタイトルと本文を入力するフォームは同じものを使い回せばコード量を削減できますよね。
そんなときに部分テンプレートとしてフォーム部分を別ファイルに書き出してしまって汎用化させます。
部分テンプレート用のファイルは頭にアンダーバー(_)を付けます
# posts/_form.html.erb <%= form_with model: post, local: true do |f| %> <%= f.label :title %> <%= f.text_field :title, class: 'form-control' %> <%= f.label :body %> <%= f.text_area :body, class: 'form-control' %> <%= f.submit class: 'btn btn-primary' %> <% end %>
新規投稿ページで呼び出してみます
呼び出す際はアンダーバーは付けません。
# posts/new.html.erb <%= '新規投稿' %> <%= render partial: 'form' %> # 下の形に省略可 <%= render 'form' %> # 同じディレクトリにある場合はディレクトリ名を省略できます
部分テンプレート内で変数を使用する場合はlocalsオプションで変数を定義します。
<%= render partial: 'form', locals: { post: @post } %> # { 部分テンプレート内で使う変数 : 変数に入れる値 } # 下の形に省略可 <%= render 'form', post: @post %>
わざわざインスタンス変数をローカル変数に定義し直すのは、パーシャルの中でインスタンス変数を参照してしまうと、パーシャルとコントローラが密結合してしまってパーシャルの再利用性が低くなるからです。
次はcollectionオプションを見てみます。
posts/index.html.erbで全てのpostを表示する次のようなコードがあったとします
<% @post.each do |post| %> <%= post.title %> <%= post.body %> <% end %>
タイトルと本文の部分は部分テンプレート化できそうです。
# _post.html.erb
<%= post.title %>
<%= post.body %>
これをeachで回すと
<% @post.each do |post| %> <%= render 'post', post : @post %> <% end %>
となります。
これをさらに
<%= render partial: 'post', collection: @posts %>
さらに
<%= render @posts %>
と、ここまで省略できます。
最後に
今までふわっとした理解で使っていましたが、アウトプットを通して少し理解が深まった気がします。
他にもオプションがあるようですが僕が今まで使ってきたもののおさらいなので以上としておきます。
もし間違っている箇所がありましたらコメントいただけますと幸いです。
最後まで読んでくださりありがとうございました。