【初学者向け】_urlや_pathといったヘルパーメソッドの使い方

#はじめに
Progateなどの学習教材ではform_tagやlink_toのパスを「"/posts/new"」のように文字列を記述しています。しかしURLを変更したくなった際に修正する箇所が多くなったり、設定によってリンクが機能しなくなることからRailsではあまり推奨されている方法ではありません。

そこでここではヘルパーメソッドについて、出来るだけ分かりやすく解説するので一緒に学んでいきましょう！

なお私もRailsの経験が浅いため、何か間違っていることや気になる点があればコメント頂けると幸いです。

#URLヘルパーメソッドとは
簡単に説明すると与えられたコードからパスを推測して返すメソッドです。

具体的に説明すると

```ruby:routes.rb
Rails.application.routes.draw do
  resources :posts
end
```

このようなルーティングを設定したアプリを用意します。

>resources :postsが何やってるか分からないよって方はこちらのページを参考にしてください。ルーティングを非常に簡単に行えるので是非覚えましょう！
[resourcesメソッドについて](https://qiita.com/fumitrial8/items/5b98ee8da261363bd51d)

この場合はパスとヘルパーメソッドの関係は下のようになっています。

| パス             |    ヘルパーメソッド    |
|:---------------:|:------------------:|
| /posts          | posts_path         |
| /posts/new      | new_post_path      |
| /posts/:id/edit | edit_post_path(:id)| 
| /posts/:id      | post_path(:id)     |
posts_pathだけ複数形になっていることに注意しましょう！

またパスとヘルパーメソッドの関係はターミナルから`rails routes`と打っても確認できます。

```ruby:Terminal
$ rails routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    posts GET    /posts(.:format)                                                                         posts#index
                          POST   /posts(.:format)                                                                         posts#create
                 new_post GET    /posts/new(.:format)                                                                     posts#new
                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
       rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
```
左がヘルパーメソッドに渡すコードで右がそれによって返されるパスですね。

#文字列でパスを渡す場合との比較
link_toメソッドにパスを渡す際に文字列で渡す場合をヘルパーメソッドに置き換えるとこうなります。

```
<%= link_to "記事一覧", "/posts" %>
~>  <%= link_to "記事一覧", posts_path %>

<%= link_to "新規投稿", "/posts/new" %>
~>  <%= link_to "新規投稿", new_post_path %>
```
#_urlと_pathの違い
これに関しては以下の記事がよくまとまっていました。
[_pathメソッドと_urlメソッドの使い分け](https://qiita.com/higeaaa/items/df8feaa5b6f12e13fb6f)
使い分けに関しては基本的に`_path`でよくて、redirect_toは完全なURLが求められるので`_url`を使うようにしましょう。(一応`_path`でもほとんどの場合は動きます)

#ヘルパーメソッドにIDなどを渡す場合
edit、show、destroyのアクションの際にはヘルパーメソッドにidを渡すことになりますが、私はこれを理解するのに色々調べてみたものの言ってることがイマイチ分からない記事が多くて詰まりました...

例えばeditのパスを渡す際のことを考えると`edit_post_path(:id)`のように渡すことになりますが、ビューでこのような使い方をすることはありません。

例えばビューで下のように記事を一つずつ取り出して、それぞれのパスを指定する場合は以下のようになります。

```ruby:posts_controller.rb
  def index
    @posts = Post.all
  end
```

コントローラーは上のようにします。

**文字列でパスを指定する場合**

```ruby:index.html.erb
<% @posts.each.do |post| %>
 <%= link_to "記事編集", "/posts/#{post.id}/edit" %>
<% end %>
```

**ヘルパーメソッドを使用する場合**

```ruby:index.html.erb
<% @posts.each.do |post| %>
 <%= link_to "記事編集", edit_post_path(post) %>
<% end %>
```

このようにヘルパーメソッドにはidを指定して渡す必要がなく、`post.id`としなくても`@posts`から取り出した`post`を渡すだけでidを判断してくれます。これさえ知っておけば応用的な使い方は調べながら習得できると思います。もっと詳しい説明は以下を参考にしてください。
[Railsのルーティング](https://railsguides.jp/routing.html)

#最後に
いかがだったでしょうか？
最初は理解しにくい部分もあると思いますが、慣れると非常に便利なメソッドなので少しずつ移行していくようにしましょう。
分かりにくい点、誤字や認識違いの内容などありましたらコメントしてください。