0
0

More than 3 years have passed since last update.

【Ruby】ルーティングのネストとparamsについて

Last updated at Posted at 2021-08-13

作成中のアプリケーションにて苦戦した、ルーティングのネストをした際のparamsの取得についてアウトプットを兼ねて書いていきます。

機能としては、ある店舗に対するコメントができる、というよくあるクチコミサイトのような感じです。
コメントは店舗詳細ページ内で投稿ができ、投稿が成功すると詳細ページにリダイレクトされます。

ルーティングは、

routes.rb
  resources :stores do
    resources :comments, only: :create
  end

StoreモデルとCommentモデルが親子関係になっているため上記記述になっています。

次にstoresコントローラー内ですが、

stores_controller.rb
 def show
    @comment = Comment.new
    @store = Store.find(params[:id])
    @comments = @store.comments.includes(:user)
 end

2行目でCommentモデルの空のインスタンスを生成しました。
3行目ではStoreモデルから店舗のidを取得する記述をしています。

4行目では、店舗詳細ページ(@storeが含んだid)に紐づく投稿されたコメント(comments)とそれを投稿したユーザー(:uesr)全ての情報を取得しています。
N+1問題を回避するため、allではなくincrudesを使っています。

次はcommentsコントローラー内です。ここが詰まったところでした。

comments_controller.rb
def create
    @store = Store.find(params[:store_id])           #店舗idを取得しています
    @comment = Comment.new(comment_params)            #空のインスタンスにcomment_paramsメソッドで取得したparamsの情報を入れています
    if @comment.save
      redirect_to store_path(@store)                             #保存ができた場合、詳細ページにリダイレクト
    else
      @comments = @store.comments.includes(:user)  #保存ができなかった場合、詳細ページがレンダリングされます。
      render "stores#show"
    end
end

private
def comment_params
    params.require(:comment).permit(:content).merge(user_id: current_user.id, store_id: params[:store_id]) 
end

createアクション内の上から2行目と、下から4行目のprivateメソッド内のcomment_paramsメソッドでparams[:store_id]としています。
idを取ってくるだけならparams[:id]で良さそうです…がこれだと取得できません。

rails routesコマンドをすると理由がわかりました。

store_comments POST   /stores/:store_id/comments(.:format)    comments#create

:idではなく:store_idとなっています。ここが私的に大きなポイントでした。

結論:rails routesはすごい

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