web-dev-qa-db-ja.com

Rails名前付きルートヘルパーとパラメーターを使用するには?

このルートを与えられた

_match 'posts/hello/:name/:title' => 'post#show', :as => :hello
_
  • _hello_path_を呼び出す方法は何ですか?

  • hello_path(@post)を呼び出すと、何をしようとしますか?

_:name_および_:title_ファイルがパスに自動的にバインドされることを望んでいましたが、Railsはモデルオブジェクトから:idを取得する方法のみを知っているようです。

代わりに、次のように呼び出す場合にのみ機能します

_<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>
_

(適切なドキュメントの欠如は本当に私を殺している)

27
Ant

2つの質問に答えるには:

  • コマンドラインでrun _rake routes_を実行して、アプリにどのルートがあるかを確認します。名前付きルートを使用できるすべての方法が表示されます。左側に表示されるルートの名前に「_path」または「_url」を追加するだけです。
  • hello_path(@post)を呼び出すと、そのhelloインスタンスのshowページへのURLが生成されます。

あなたがそれを呼ぶ方法は標準です:

_<%= link_to "link2", hello_url(:name=> @post.name, :title=>@post.title) %>
_

ただし、これも機能する場合があります。

_<%= link_to "link2", hello_url(@post.name, @post.title) %>
_

ここにいくつかのドキュメントがあります(Rails APIを除く)これは役立ちます。 http://guides.rubyonrails.org/routing.html

17
GregT

hello_pathは何をしようとしますか?」という質問に答えるために

hello_pathは、取得するパラメータの数を知っています。これは、config/routesの名前付きパラメーターのカウントからです。ハッシュまたは引数のリストのいずれかを受け入れます。ハッシュを指定する場合、キーはURLパラメーターの名前と一致する必要があります。引数のリストを指定すると、位置(最初の名前付きパラメーターを持つ最初の引数)で一致します。

次に、to_param oneachパラメーターを個別に呼び出してから、それらをすべて結合します( ここのコードを参照、4.0ブランチ =)。

2つ以上のパラメータが必要なときにオブジェクトを渡すと、オブジェクトでto_paramを呼び出すことすらできません。スタックトレースなしで次のようなエラーが発生した場合
No route matches {:controller=>"posts", :action=>"show", :id=>#<Post ...>}

1つの名前付きパラメーターの使用

名前付きパラメーターが1つしかない場合は、非常に簡単です。 IDではなく名前で投稿を検索する必要がある場合は、to_paramを再定義するだけです。

class Post < ActiveRecord::Base
  ...
  def to_param
    name
  end
end

複数の名前付きパラメーターの使用

しかし、URLに複数の名前付きパラメーターがある場合、to_paramを再定義するだけでは十分ではありません。これを試したとしましょう:

# app/models/post.rb
class Post < ActiveRecord::Base
  ...
  def to_param
    {name: name, title: title}
  end
end

# app/views/posts/index.html.erb
<%= post_path(post) %>

この場合、十分な引数をpost_pathに渡していないため、ルーティングエラーが発生します(上記を参照)。 これを回避するには、to_paramを明示的に呼び出します:

 # app/views/posts/index.html.erb
 <%= post_path(post.to_param) %>

これは、ほとんどのRailsルーティングマジックよりも少し滑らかではありませんが、完全にうまく機能します。後で投稿の検索方法を変更する場合、to_paramを再定義するだけです。 post_pathを呼び出したすべての場所を心配する

フードの下

参照する関連コードは actionpack/lib/action_dispatch/routing です

14
declan

このように呼び出すこともできます

hello_path(@post.name, @post.title)

それが役に立てば幸い。

6
James

他の回答(この記事を書いている時点では)は問題ありませんが、GregTの回答に対するあなたの回答はRailsについての理解不足を示しています。

具体的には、Railsの背後にある3つの主要な原則:convention over configurationmodel-view-controller architecture(MVC)、および[〜#〜] rest [〜#〜]。あらゆる始まりの始まりにあるものRails本。初心者はコードで最初の章にジャンプできると思うことがよくありますが、Railsは他の多くのトピックとは異なりますというのは、最初の章は重要な概念を説明しているだけでなく、章の紹介者ではありません。Railsは「コード」ではないので、「フレームワークのコード」です。

「構成より規約」とは、特定の規則に従えば、Railsに組み込まれた動作の恩恵を受けることを意味します。ルーティングは、最大ではないにしても、それらの領域の1つであり、完全に構成可能ではありますが、コンベンションは開発者に利益をもたらします。

特定のルーティング形式に従うパスは、コントローラー、アクション、および場合によってはid、形式、および追加パラメーターに解析されます。デフォルトでは、少なくとも、Rails(およびSinatra)パスは、次の形式と順序を取ります。

/controller_name/action_name

それよりも少し複雑で、より多くのオプションがあり、実際には次のように見えます:

/controller_name/action_name/(id)(.format)(?param=value)(&...)

...しかし、この答えに必要な詳細よりも詳細です。

controllerは、MVCのC、またはリクエストを処理するクラスです。 actionは、そのコントローラー内の7つのRESTfulアクション(indexshownewcreateeditupdatedestroy)の1つです。すべてのアクションがID(indexnew、およびcreate)を必要とするわけではなく、それらのすべてがget要求(ビューを生成する要求、たとえばdestroycreateおよびupdateにビューがありません)ではありません。

すべてをまとめると、次の例が表示されます。

/articles/edit/1

... id 1を渡すArticlesControllerコントローラーの 'edit'アクションにリクエストをルーティングします。コントローラーが認証や承認などのハウスキーピングを実行してから、Articleモデルを取得することが期待されています([〜#〜 ] m [〜#〜] CV)ID 1で「編集」ビューに渡します(MC [〜#〜] v [〜#〜])。

特に新しいRails=開発者にとっては、これらの規約に固執し、おそらくRESTによって提供されるものを超えるいくつかの追加アクションを追加することが最善です。

Routes.rbファイルで、RESTに従わない代替ルーティングスキームなどを設定することにより、この規則の外に出ることができますが、上流に泳いでいるサケのようになります-フローを使用するよりもはるかに困難です。その道をたどる(しゃれた)場合は、自分で多くの追加作業を行い、おそらく車輪をいくらか再発明し、Railsフレームワークによって提供される利点を失います。何らかの理由でその状況、おそらくRailsはあなたの仕事にふさわしいツールではありません。

5
IAmNaN