ЯoomeR

プログラミング~実装とエラー解決と、時々、AI~

パスに引数を記述する方法

アプリの例

例えば、投稿の詳細ページから編集できるアプリを考えよう。

コントローラー、ビューの記述は以下の通りである。

#post_controller.rb

def edit
 @post= Post.find(params[:id])
end

def show
 @post= Post.find(params[:id])
end
#show.html.erb

<%= link_to "編集する", edit_post_path(@post)%>

なぜパスに引数を記述する必要があるのか?

どの投稿(post)の編集ページに遷移するかを明示するためである。

rails routesを実行すると以下のように表示される。

edit_post GET    /posts/:id/edit(.:format)               posts#edit
post      GET    /posts/:id(.:format)                    posts#show
          PATCH  /posts/:id(.:format)                    posts#update
          PUT    /posts/:id(.:format)                    posts#update
          DELETE /posts/:id(.:format)                    posts#destroy

editのURIを見ると、「/posts/:id/edit(.:format)  」と記載されている。

つまり、idの情報が必要なのである。

直感的にも、「どの投稿を編集ページなのか」を特定するためにはid情報が必要だということが分かるはずである。

edit_post_path(@post)は、「edit_post_pathに遷移してください。対象のpostはコントローラー(のshowアクション)で定義した@postです。」という意味である。

idを引き渡すための記述なので、より細かく記述するなら、「edit_post_path(@post.id)」となる。(@postでも良い理由は、@postの情報からrailsが勝手にid情報を見つけてくれるからである。)

引数がなくても遷移できるんだが?

今回の例のアプリでは、引数を記述しなくても適切に編集ページに遷移できる。

なぜ引数がなくても特定のpostの編集ページに遷移できるのだろうか。

それは、詳細ページ(show.html.erb)の時点でURIにidが含まれているからである。

現在のURIに含まれているidを元に、railsが自動的に判断している。

よって、異なる対象に移動する場合は、引数がないとエラーが発生する。

エラー例

#投稿したpostの情報
id=5 content=”5番目の投稿です’ user_id=1

#投稿者の情報
id=1 nickname=”一番目太郎’ 

投稿(post)のidは5であり、投稿者(user)のidは1である。

投稿の詳細ページから、「一番目太郎の投稿一覧」に遷移したいとする。

#パスの例
<%= link_to "by #{@post.user.nickname}", user_path%>

引数を記述していないので、現在のパス(投稿の詳細ページのURI)に含まれている「id=5」という情報を元に遷移が行われる。

結果、「id=5のユーザーの投稿一覧」を表示しようとしてエラーが発生する。

(user does”t exist id=5 などのエラーが出る。)

投稿者の投稿一覧へのパス

以下のようになる。

<%= link_to "by #{@post.user.nickname}", user_path(@post.user)%>

流れとしては、

「post_controllerのshowアクション」
↓
「posts/show.html.erb」
↓
「users/show.html.erb」

となる。

スタート地点はpostコントローラーである。

よって、userの情報もpostを起点として手に入れることが好ましい。

故に、引数はコントローラーに定義した@postを起点として、「@post.user」としている。