Rails link_toメソッドの引数にモデルのインスタンスを直接渡したら、showに遷移できる

開発中にわからなかったことについて調べたので、備忘録も兼ねて投稿します。

環境

概要

link_toメソッドの引数には以下の2つをとります。

  1. リンクのテキスト
  2. パスやURL

以下は、ボードの一覧ページから詳細ページに遷移するリンクを表示する例です。

<% @boards.each do |board| %>
    ...
    <%= link_to '詳細', "/boards/#{board.id}" %>
<% end %>

第2引数にURLを直接指定しています。

Railsの学習を始めたばかりで、link_toでリンク先を指定して遷移させられるのね、と腹落ちしていたところ、以下のように第2引数にパスでもURLでもないものが使われているのを見ました👀!

<% @boards.each do |board| %>
    ...
    <%= link_to '詳細', board %>
<% end %>

なぜか問題なく詳細ページに遷移できていたので、どういうことなのか調べました。

結論

Railslink_toメソッドは、非常にスマートなようで。

第2引数としてモデルのインスタンスを直接渡すことで、そのインスタンスshowアクションへのパスを自動的に生成できるようです!

モデルのインスタンスを直接指定して、showアクションのURLに遷移する方法

どうやってそれが可能なのか?

リソースベースのルーティングを使用する必要があります。

resourcesメソッドを使ってルーティングを定義すると、Railsは一連の標準的なルート(URLパターン)を自動的に生成します。そして、それぞれのルートには特定の命名規則があります。

例:

resources :boards

上記のようにルーティングを定義すると、以下のようなURLパターンが自動的に生成されます:

  • /boards: 全てのボードのリスト(indexアクション)
  • /boards/:id: 特定のボードの詳細(showアクション)

ここで、:idはボードのID(モデルのインスタンスのID)を示します。

実際の使い方:

今回はBoardsControllerの中で、ボードの一覧を取得して表示するためのindexアクションと、特定のボードの詳細を表示するためのshowアクションを定義します。

class BoardsController < ApplicationController
    def index
    @boards = Board.all
  end
  
  def show
    @board = Board.find(params[:id])
  end
end

ボードの一覧ページに各ボードの詳細ページへのリンクを作成したい場合、/boards/index.html.erbで以下のように書くことができます:

<% @boards.each do |board| %>
  <%= link_to '詳細', board %>
<% end %>

上記のlink_toメソッドでは、第2引数にboard(ボードのインスタンス)を直接指定しています。

これにより、Railsは自動的に/boards/:idの形式のURLを生成します。

そして、:idの部分には、boardインスタンスのIDが埋め込まれます。

まとめ

Railslink_toメソッドについて以下のことがわかりました。

  • モデルのインスタンスを直接渡すだけで
  • 詳細ページへ遷移するリンクを作ることができる

そのためには、

  • リソースベースのルーティングと組み合わせる必要がある

参考

link_toメソッドを使ったリンクの作成