記事について
備忘録です。
routes.rbにて親子関係を作った場合の、子コントローラーのredirect_toの書き方について記します。
私は今までネストされた子コントローラーのcreateアクションや、updateアクションのリダイレクト先をroot_pathで済ましていました。
脱root_pathを目指します。
前提
親:contents
子:descriptions
root to: 'contents#index'
resources :contents, only: [:index, :new, :create, :show, :edit, :update] do
resources :descriptions, only: [:new, :create, :edit, :update, :destroy]
上記のように、子には:showが指定されていないこととします。
※便宜上、onlyオプションで記述しています。
root_pathで指定した場合
(前略)
def new
@description = Description.new
end
def create
@description = Description.new(description_params)
if @description.save
redirect_to root_path #ココです
else
render :new
end
end
def edit
end
def update
if @description.update(description_params)
redirect_to root_path #ココです
else
render :edit
end
end
(後略)
このように、"redirect_to root_path"とすることで、ネスト親のcontents#indexに飛ぶことができます。
しかし、情報を更新した後にトップページに飛んでしまうとユーザーにとって何かと不便です。
わざわざトップページからその更新した情報までクリックしていき、いくつものページを遷移していかないといけません。
そこで、脱root_pathをしようと考えました。
脱root_pathの場合
def new
@description = Description.new
end
def create
@description = Description.new(description_params)
if @description.save
redirect_to content_path(@description.content_id) #ココです
else
render :new
end
end
def edit
end
def update
if @description.update(description_params)
redirect_to content_path(@description.content_id) #ココです
else
render :edit
end
end
root_pathの記述を消して、content_path(@description.content_id)と書き換えました。
このように記述することで、"/contents/4/descriptions/new" や "/contents/3/descriptions/edit"などのページから"/contents/1/"へリダイレクトでき、親のshowと同じ動きができます。
考え方
1つずつ見ていきます。
prefixに注目してみると、contentと書いてあるので、redirect_to content_pathと書きます。
(前略)
def create または def update
@description = Description.new(description_params)
if @description.save
redirect_to content_path #ココです
else
(後略)
上記のように、"content_path"と記述することで"/contents/"までの動きができます。
しかし、まだ不完全です。どのidに該当するページに遷移したいのか記す必要があります。
idを指定してあげる際のポイントは以下の2点です。
- createやupdateに至るまでのparamsを確認する
- "/contents/id/"となるように、idを指定してあげる
createやupdateまで運んできたparamsの中身を確認すると、
content_idが含まれていることがわかります。
なので、paramsを持っているインスタンス変数(@description)を指定してあげて、その中(.)の"id"(content_id)を指定してあげれば良いわけです。
(前略)
def create または def update
@description = Description.new(description_params)
if @description.save
redirect_to content_path(@description.content_id) #ココです
else
(後略)
最後に
データの流れ等を言語化して説明するのってなかなか大変だなあと書いていて思いました。。
私自身プログラミング初学者なので、至らない点がございましたらご指摘お願いいたします。
参考記事