Rails のパスヘルパー(_path と _url) の違いと使い方

はじめに

Rails では、コントローラやビューなどでリンクを生成するときにパスヘルパーを利用します。
多くの場合、_path_url という2種類が提供されているのですが、それぞれが何を意味しているのかが曖昧で、初めて見る人は混乱するかもしれません。

たとえば、articles_patharticles_url はどのような違いがあるのでしょうか。
それらは動作上どのように変わり、実務のどのような場面で使い分けるのが望ましいのでしょうか。

本記事では、この2つの違いと具体的な使い方をわかりやすく説明していきます。
初心者の方でも理解できるように、丁寧かつ具体的な例を多めに紹介します。

この記事を読むとわかること

  • Rails のパスヘルパーである _path_url の基本的な違い
  • コントローラやビューなどでの活用シーン
  • 実務での使い分けポイント
  • ルーティングやメール送信との関連
  • テストコードでのパスヘルパー活用例

Railsにおけるパスヘルパーとは

Rails には、ルーティングに基づいて URL を自動生成する仕組みが用意されています。
たとえば、resources :articles とルーティングを設定すると、articles_pathnew_article_path といったメソッドが自動的に定義されます。
これらは「パスヘルパー」と呼ばれ、コントローラやビュー、またはメールテンプレートでも利用できます。

パスヘルパーを使うと、URL 文字列をハードコーディングすることなく、シンボリックに参照できるのが大きなメリットです。
ルートの変更やパラメータ追加などがあっても、パスヘルパーを通じて自動的に URL を生成するため、コードの保守性が高まります。

Rails のルーティングファイル(config/routes.rb)で定義したパスに基づいて、Rails はパスヘルパーを自動生成します。
たとえば、articles_path は「記事一覧ページへのパス」を返し、edit_article_path(@article) は「記事を編集するためのパス」を返します。

_path と _url が生まれる背景

Rails のパスヘルパーには、基本的に同じ名前で「_path」が末尾につくものと「_url」が末尾につくものがあります。
どちらも同じルートを表すヘルパーですが、実はここに「相対パスか、絶対パスか」の違いがあります。

Rails で Web アプリケーションを開発する際、コントローラやビュー内でリンクを生成するときは多くの場合 _path で十分です。
しかし、メール本文に記載する URL のように、実際のドメイン名を含む絶対URL が必要になるケースも存在します。

こうした背景から、Rails ではシチュエーションに応じて相対パスを返す _path と、フルのドメイン名を含む絶対URLを返す _url が用意されるようになりました。
これによって、リンク先の形式を柔軟に選べるようになっています。

_path と _url の基本的な違い

_path ヘルパー:

  • ドメインを含まない、サーバー内でのパス部分(相対パス)を返します。
  • 例: "/articles" のような文字列。

_url ヘルパー:

  • プロトコルとドメインも含んだ完全な絶対URLを返します。
  • 例: "https://example.com/articles" のような文字列。

たとえば、アプリケーションのドメインが https://example.com だとして、Rails で定義されたルートを resources :articles とする場合、以下のヘルパーが利用できます。

articles_path # => "/articles"
articles_url  # => "https://example.com/articles"

コントローラの中で redirect_to articles_path と書くと、相対パスによるリダイレクトが行われますが、多くのケースでは Rails が内部的に正しく処理してくれるため、通常の画面遷移なら _path で問題ありません。
一方で、ユーザーに送るメールの中に「外部ブラウザから直接アクセスしてほしいページリンク」を埋め込みたい場合は、絶対URLが必要になることが多く、_url を使います。

使われる場面の違い

_path ヘルパーを使うとき

ビュー内でのリンク生成

たとえば link_to "記事一覧", articles_path のような形で、アプリ内のページへ遷移させたい場合。

コントローラのリダイレクト

たとえば redirect_to article_path(@article) のように、同じアプリケーション内の別アクションへリダイレクトする場合。

フォームの action 属性

Rails のフォームヘルパーを使うと自動的に _path が使用されるケースが多いため、通常意識せずとも _path 形式が用いられます。

_url ヘルパーを使うとき

メール本文など、絶対URLが必要な場面

外部環境からのアクセスを考慮し、ブラウザのウィンドウ外から直接アクセスしてもらいたい場合。

外部サービスのコールバックURLとして利用

OAuth や Webhook など、コールバック用に完全な URL を求められる場面で _url を指定するケース。

別ドメインで動作するアプリにリンクを渡すとき

Rails 環境が複数に分かれている場合など、フルのURL指定が必須なケース。

ルーティングの設定とパスヘルパーの関連

Rails のパスヘルパーは、ルーティングの設定に基づいて自動生成されます。
たとえば、以下のように config/routes.rb で設定した場合を考えてみましょう。

Rails.application.routes.draw do
  resources :articles
end

上記の設定で、以下のようなパスヘルパーが使えるようになります。

  • articles_path / articles_url: 記事一覧ページ
  • new_article_path / new_article_url: 記事作成ページ
  • edit_article_path(:id) / edit_article_url(:id): 記事編集ページ
  • article_path(:id) / article_url(:id): 個別記事ページ

つまり、ルーティングで設定した内容に応じて _path_url の両方のメソッドが自動で定義されるため、それを呼び出すだけでパスやURLが取得できるわけです。

コントローラでの活用例

コントローラでは、アクションの最後にリダイレクトやレンダリングを行うのが一般的です。
パスヘルパーはこのリダイレクト処理で頻繁に使われます。
例として、記事を更新後に一覧ページへ飛ばす場合は、以下のように書きます。

def update
  @article = Article.find(params[:id])
  if @article.update(article_params)
    redirect_to articles_path, notice: "記事を更新しました。"
  else
    render :edit
  end
end

このとき、articles_path は相対パスを返します。
もし絶対URLでリダイレクトしたい場合は articles_url を使いますが、同一ドメイン内で移動するだけなら _path で十分です。

また、別のコントローラから記事の詳細ページへ飛ばすときは article_path(@article) という形で利用します。
複数の画面を行き来するとき、ハードコードした URL ではなくパスヘルパーを使うのが安全で保守性も高いといえます。

ビューでの活用例

ビューの中では link_to ヘルパーなどで、URL を指定する場面が多いです。
以下のように、記事一覧ページへのリンクを作る場合を考えてみましょう。

<%= link_to "記事一覧", articles_path %>

これにより、/articles というパスへのリンクが生成されます。
同じように絶対URLが必要な場合は、<%= link_to "記事一覧", articles_url %> と書くことで、https://example.com/articles のようにドメインを含むリンクになります。

その他にも、画面上に直接 URL を表示したい場合などでも、パスヘルパーを使えば簡単にリンク文字列を生成できます。
たとえば、以下のような形です。

<%= articles_url %> <!-- "https://example.com/articles" が表示される -->

リダイレクトでの活用例

Rails アプリケーションでは、フォームを送信した後や何らかの処理を行った後に、ユーザーを別のページに移動させるケースがよくあります。
その際には redirect_to を使います。

最も基本的な書き方としては、次のようになります。

redirect_to articles_path

一般的には _path を使うだけで問題ありません。
実装上、Rails がアプリケーションのホスト情報を理解してリダイレクトを実行してくれるため、articles_url を使わなくても同じドメイン内で動作します。
ただし、外部向けにリダイレクト先を示すようなケースでは _url を使うこともあります。

メール送信や外部サービスへのリンクに使う場合

Rails アプリケーションからメールを送信するときには、フルのドメイン名を含む URL でないと受信者が正しくアクセスできない可能性があります。
たとえば、パスだけが書かれた "/articles" では、受信者がクリックしても正しいサイトに飛べなくなってしまいます。

そこで、メール本文内のリンクには _url を使うのが一般的です。
たとえば、次のように書くと、フルパスが生成されます。

<%= link_to "記事一覧をチェック", articles_url %>

また、外部サービスの OAuth コールバックURLや Webhook の設定画面にも絶対URLが求められる場合が多いです。
そのとき、Rails が提供する _url ヘルパーを使って渡すことで、外部サービスに正しいコールバック先を登録できます。

_url を使うときの注意点(環境別URLなど)

_url ヘルパーは絶対URLを返すため、Rails に設定されたホスト名プロトコル に依存します。
開発環境では localhost:3000、本番環境では example.com のようにホスト名が違うことはよくあります。
このホスト名は config/environments/production.rbconfig/environments/development.rb などで設定するパラメータによって変わります。

もし環境ごとに適切にホスト名を切り替えていないと、メールに記載されたリンク先が正しく動かないケースが発生するかもしれません。
そのため、メールや外部サービスとの連携時には、環境別のホスト設定 を確認して _url ヘルパーを使うことが大切です。

環境設定ファイルで config.action_mailer.default_url_options などを正しく設定しないと、_url ヘルパーから意図しないドメインが返されることがあります。

_path を使うときの注意点(相対パスの使い方)

_path ヘルパーはドメインを含まない相対パスを返すため、基本的にはアプリケーション内での遷移に利用します。
ただし、アプリケーションがサブディレクトリ配下に配置されているケース(例: https://example.com/myapp/)では、Rails 側の設定でベースとなるパスを調整しておかないと、リンク切れが起こる可能性があります。

また、JavaScript で動的に _path の値を取得して何かのリクエスト先として使う場合は、念のためルートのパターンが期待通りか確認したほうがよいでしょう。
フロントエンドと組み合わせて API をコールするときには、_url が必要になるケースと _path で足りるケースが混在するので注意が必要です。

ルーティングの確認方法

Rails で定義されているルーティングは、ターミナルで以下のコマンドを実行することで確認できます。

rails routes

これにより、Prefix 欄に articlesnew_article などの名前が表示されます。
同じ行の Path 欄から、実際に生成されるパスがわかります。
パスヘルパーを使うときは、この Prefix"_path" とか "_url" を足せば OK です。

たとえば、Prefixarticles なら articles_patharticles_url が存在し、Prefixnew_article なら new_article_pathnew_article_url が用意されています。

実務でのよくあるパターン

実務では、どのように _path_url を使い分けることが多いのでしょうか。
以下に、よくあるパターンを挙げます。

  1. 通常のアプリ内の画面遷移やリンク生成: _path を使う

    • 同じアプリ内の画面遷移であれば、相対パスで十分に処理できます。
    • SEO 上の影響も特にありませんし、Rails も _path を前提に多くのヘルパーが設計されているため、こちらがデフォルト。
  2. メールや外部サービス連携: _url を使う

    • 受信者が外部から直接アクセスすることを想定するため、絶対URLを明記する必要があります。
    • コールバックURLをサービスに登録するときなども同様で、プロトコルから明示する必要がある。
  3. API のエンドポイントを返すとき: シチュエーションによって _url

    • JSON レスポンスや外部公開 API などで、フルパスを渡したい場合があります。
    • API 同士の連携で相手方が完全な URL を必要とする場合、_url を生成してレスポンスに含める。

一方で、リダイレクト時にも _url が使えますが、同一ドメイン内であれば _path でほとんど問題ありません。
結果的に、本当に必要なシーン以外は _path を使う場面が多いと言えます。

テストコードでのパスヘルパー活用

RSpec や Minitest などでコントローラやビューをテストするときにも、パスヘルパーが活用される場面があります。
例えば、リクエストスペックで get articles_path のように書くと、記事一覧を取得するテストが簡単に書けます。

テストコードで _url を使う場合も、メール送信のテストや、外部へリダイレクトする機能のテストなど特定の場合だけです。
通常の画面遷移検証では _path があれば十分です。

アプリ全体の設計におけるパスヘルパーの考え方

Rails アプリケーションを設計するうえで、URL 設計 は大きなポイントになります。
ユーザーに対してわかりやすい URL かどうか、SEO 的に適切か、など様々な角度から検討する必要があります。

URL をどのように設計しても、Rails ではそれに合わせてルーティングを設定し、パスヘルパーを使ってリンクを生成するだけです。
アプリ全体のリンク構造を変更するときも、実際のコード中でハードコードした部分がなければ大きく改修しなくても済みます。

Rails では URL を直接書くより、パスヘルパーを使う方が保守性が高くなります。 あちこちに生 URL が記載されると、ルート構造を変えるたびに手動で修正しなければならなくなるからです。

まとめ

Rails のパスヘルパーには _path_url の2種類があることを解説しました。
いずれも同じルートを指すヘルパーですが、下記のような使い分けがポイントになります。

  • _path: 相対パスを返す。通常のアプリ内遷移で使用する
  • _url: ドメインやプロトコルを含んだ絶対URLを返す。メールや外部サービス連携に必須

ルーティングを設定すると、自動的に両方のパスヘルパーが作られるので、実装時にはどちらを使うかを目的別に選んでみてください。
コントローラ・ビューともに _path で事足りるケースが大半ですが、絶対URLが求められる状況なら _url を使いましょう。

実務では、環境ごとのホスト名設定や複数のサービス連携など、想定外のリンク生成が必要になることがあります。
そういった場合にも、本記事でご紹介したポイントを押さえていれば、Rails のパスヘルパーをうまく使い分けられるでしょう。
今後の開発で役立てていただければ幸いです。

Rubyをマスターしよう

この記事で学んだRubyの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。