renderを勘違いしていたので整理。
renderメソッド
renderメソッドは、呼び出すビューファイルを指定することができる。
render :edit
コントローラー内で使用するメソッドだが、処理がうまくいかなかったときに、元のページに戻る処理で使われることが多い。
理由は、元のページのデータをそのまま保持することができるため。
redirect_toメソッド
redirect_toメソッドは、指定のurlへ遷移するようリクエストを送信している。
コントローラー内で使用し、pathやURLを指定する。
redirect_to root_path
renderがビューファイルを指定しているのに対して、redirect_toは再度ルーティングを通してコントローラーで処理が行われている。
renderメソッドでのビュー再表示
renderメソッドは便利で、フォームでの入力ミスがあった時でも、元のページに戻り、かつ入力値が残ったままになる。
しかし、ビュー内で他のコントローラーに定義されているインスタンス変数を使用している場合、再度インスタンス変数の定義が必要となる。
Postsコントローラーでユーザーの投稿詳細を見るshowアクションにコメント投稿欄とコメント表示していた場合。
def show
@comment = Comment.new
@comments = @post.comments.includes(:user)
end
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.new
if @comment.save
redirect_to post_path(@post)
else
@comments = @post.comments.includes(:user)
render "posts/show", status: :unprocessable_entity
end
end
commentsコントローラーでは保存が失敗したらpostsコントローラーのビューファイルshowを呼び出すが、postsコントローラーを経由しないため、再度@comments = @post.comments.includes(:user)でpostへのコメント一覧を取得する必要がある。
まとめ
同じビューに戻ると思っていたが、コントローラーを経由しないため、アクションが呼び出されないので必要なインスタンス変数は再定義が必要ということを学びました。