LoginSignup
1
0

More than 3 years have passed since last update.

【Ruby On Rails】脱root_path! ネスト"子"のビューから、ネスト"親"の:showへリダイレクト記述法

Last updated at Posted at 2020-12-29

記事について

備忘録です。

routes.rbにて親子関係を作った場合の、子コントローラーのredirect_toの書き方について記します。

私は今までネストされた子コントローラーのcreateアクションや、updateアクションのリダイレクト先をroot_pathで済ましていました。

脱root_pathを目指します。

前提

親:contents
子:descriptions

routes.rb
root to: 'contents#index'

resources :contents, only: [:index, :new, :create, :show, :edit, :update] do
    resources :descriptions, only: [:new, :create, :edit, :update, :destroy]

上記のように、子には:showが指定されていないこととします。
※便宜上、onlyオプションで記述しています。

rails routes↓
スクリーンショット 2020-12-29 18.59.36.png

root_pathで指定した場合

descriptions_controller
(前略)

  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の場合

descriptions_controller.rb
  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つずつ見ていきます。

もう一度ルーティングを確認します。
スクリーンショット 2020-12-29 18.59.36.png

prefixに注目してみると、contentと書いてあるので、redirect_to content_pathと書きます。

descriptions_controller.rb
(前略)

    def create または def update
    @description = Description.new(description_params)
    if @description.save
      redirect_to content_path #ココです
    else

(後略)

上記のように、"content_path"と記述することで"/contents/"までの動きができます。
しかし、まだ不完全です。どのidに該当するページに遷移したいのか記す必要があります。

idを指定してあげる際のポイントは以下の2点です。

  1. createやupdateに至るまでのparamsを確認する
  2. "/contents/id/"となるように、idを指定してあげる

createやupdateまで運んできたparamsの中身を確認すると、

スクリーンショット 2020-12-29 19.26.07.png

content_idが含まれていることがわかります。
なので、paramsを持っているインスタンス変数(@description)を指定してあげて、その中(.)の"id"(content_id)を指定してあげれば良いわけです。

descriptions_controller.rb
(前略)

    def create または def update
    @description = Description.new(description_params)
    if @description.save
      redirect_to content_path(@description.content_id) #ココです
    else

(後略)

最後に

データの流れ等を言語化して説明するのってなかなか大変だなあと書いていて思いました。。
私自身プログラミング初学者なので、至らない点がございましたらご指摘お願いいたします。

参考記事

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