Edge Railsのネストされたリソースに関する私の理解として、
link_to 'User posts', @user.posts
指し示す
/users/:id/posts
?
ルート.rbファイルには
map.resources :users, :has_many => :posts
これがデフォルトの動作でない場合、何か他のことを実行して達成できますか?
リシャフと同じように:
_link_to "User Posts", [@user, :posts]
_
私のブログ からの説明です。
Railsの本当に早い段階で、次のようなルートを作成します。
_redirect_to :controller => "posts", :action => "show", :id => @post.id
_
これにより、show
内のPostsController
アクションに忠実にリダイレクトされ、_@post.id
_が返す値を使用してid
パラメーターが渡されます。典型的な302応答。
次に、Rails 1.2が登場し、次のようなルーティングヘルパーを使用できるようになりました。
_redirect_to post_path(@post)
_
そして人々は喜んだ。
これは実質的に同じことを行います。ここで_post_path
_は、_@post
_のように見える_/posts/1
_オブジェクトを使用してルートを構築し、_redirect_to
_はそのルートに302応答を返し、ブラウザはそれに従います。
その後、それ以降のバージョン(どれを思い出せないか)では、次のような構文が許可されました。
_redirect_to @post
_
そして人々は二度目に喜びました。
十分に進んだ技術は魔法と見分けがつかない。
これは魔法のように見えますが、そうではありません。これがしていることは、実際には非常に、非常にきちんとしています。 _redirect_to
_メソッドは、その従兄弟である_link_to
_および_form_for
_と同様に、_url_for
_と呼ばれる共通のメソッドを使用してURLを作成します。 _url_for
_メソッドは、上記の例のように、文字列、ハッシュ、さらにはモデルのインスタンスなど、さまざまな種類のオブジェクトを受け取ります。
それで、これらのオブジェクトでそれが何をするかは、かなりきちんとしています。上記の_redirect_to @post
_呼び出しの場合、_@post
_オブジェクトを検査し、それがPost
クラスのオブジェクトであることを確認し(とにかく)、そのオブジェクトが永続化されているかどうかを確認します。どこかでデータベースを_persisted?
_で呼び出す。
「永続化」とは、Rubyオブジェクトのデータベースのどこかに一致するレコードがあることを意味します。ActiveRecordの_persisted?
_メソッドは次のように実装されます。
_def persisted?
!(new_record? || destroyed?)
end
_
オブジェクトが_Model.new
_などの呼び出しによって作成されなかった場合、そのオブジェクトは新しいレコードにはなりません。また、destroy
メソッドが呼び出されていない場合、オブジェクトも破棄されません。これらの両方のケースが当てはまる場合、オブジェクトはレコードの形式でデータベースに永続化されている可能性があります。
永続化されている場合、_url_for
_は、このオブジェクトがどこかにあること、およびその場所が_post_path
_と呼ばれるメソッドの下にある可能性が高いことを認識しています。そのため、このメソッドを呼び出し、通常はid
であるこのオブジェクトの_to_param
_値を渡します。
要するに、それは効果的にこれを行っています:
_#{@post.class.downcase}_path(@post.to_param)
_
これはこれであることがわかります:
_post_path(1)
_
そして、そのメソッドが呼び出されると、次の小さな文字列を取得します。
_"/posts/1"
_
美しい!
これはポリモーフィックルーティングと呼ばれます。オブジェクトを_redirect_to
_、_link_to
_、_form_for
_などのメソッドに渡すと、使用するものの正しいURLを見つけようとします。
今、あなたがコーディングしているときRailsあなたは非常に昔にこのように_form_for
_を使用したかもしれません:
_<% form_for @post, :url => { :controller => "posts", :action => "create" } do |f| %>
_
もちろん、Railsの進歩により、次のように単純化できます。
_<% form_for @post, :url => posts_path do |f| %>
_
フォームはデフォルトでPOST
HTTPメソッドを持つため、_posts_path
_へのリクエストはcreate
アクションではなく、PostsController
のindex
アクションに送られます。これはGET
の場合に発生します。リクエスト。
しかし、なぜそこで停止するのですか?なぜこれを書いてみませんか?
_<%= form_for @post do |f| %>
_
個人的には、そうしない理由はありません...これほど単純なものであれば。 _form_for
_メソッドは、_url_for
_と同様に、その下に_redirect_to
_を使用して、フォームの配置先を決定します。 _@post
_オブジェクトがPost
クラス(ここでも想定)であることを認識し、オブジェクトが永続化されているかどうかを確認します。そうである場合は、post_path(@post)
を使用します。そうでない場合は、_posts_path
_です。
_form_for
_メソッド自体は、渡されたオブジェクトが永続化されているかどうかを確認し、永続化されている場合はデフォルトでPUT
HTTPメソッドになり、そうでない場合はPOST
になります。
したがって、これは_form_for
_がnew
とedit
の両方のビューで同じ構文を持つのに十分な柔軟性を持つことができる方法です。最近では、_form_for
_タグ全体を1つの部分にまとめて、new
ページとedit
ページの両方に含めることがますます一般的になっています。
したがって、通常のオブジェクトを渡す場合、_form_for
_はかなり単純ですが、オブジェクトの配列を渡すとどうなりますか?このように、例えば:
_<%= form_for [@post, @comment] do |f| %>
_
まあ、_url_for
_と_form_for
_の両方について説明しました。
_url_for
_メソッドは、これが配列であることを検出し、各部分を分離して個別に検査します。まず、この_@post
_のことは何ですか?さて、この場合、isが永続化され、IDが1のPost
インスタンスであると仮定しましょう。次に、この_@comment
_オブジェクトは何ですか。 ?これは、データベースにまだ永続化されていないComment
インスタンスです。
ここで_url_for
_が行うことは、各パーツを配列に配置し、それをルーティングメソッドに結合し、必要な引数を使用してそのルーティングメソッドを呼び出すことにより、URLヘルパーメソッドを少しずつ構築することです。
まず、_@post
_オブジェクトがPost
クラスであり、永続化されていることがわかっているため、URLヘルパーはpost
で始まります。次に、_@comment
_オブジェクトがComment
クラスのものであり、not永続化されていることがわかっているため、URLヘルパーでcomments
がpost
に従いますビルドします。 _url_for
_が現在認識している部分は_[:post, :comments]
_です。
_url_for
_メソッドは、これらの個々の部分をアンダースコアと組み合わせて_post_comments
_になり、その最後に__path
_を追加して、_post_comments_path
_になります。次に、永続化されたオブジェクトのみをそのメソッドの呼び出しに渡し、次のような呼び出しを行います。
_post_comments_path(@post)
_
そのメソッドを呼び出すと、次のようになります。
_"/posts/1/comments"
_
最良の部分? _form_for
_は、_@comment
_オブジェクトが永続オブジェクトでない場合はPOST
を使用し、永続オブジェクトである場合はPUT
を使用することを引き続き認識します。覚えておくとよいのは、_form_for
_は常に配列で指定されたlastオブジェクト用であるということです。その前のオブジェクトは、単に入れ子になっているだけです。
追加されるオブジェクトが多いほど、_url_for
_がハードヤードを実行してパスを構築する回数が多くなります... 2つの部分に保つことをお勧めします。
_form_for
_のオブジェクトを含む配列の使用について説明したので、別の一般的な使用法を見てみましょう。次のように、少なくとも1つのSymbolオブジェクトを含む配列。
_<%= form_for [:admin, @post, @comment] do |f| %>
_
ここで_url_for
_メソッドが行うことは非常に簡単です。 Symbol
があることを確認し、それをそのまま受け取ります。 url
の最初の部分は単に記号と同じです:admin
。 _url_for
_がこの時点で知っているURLは_[:admin]
_です。
次に、_url_for
_は配列の残りの部分を通過します。この場合、_@post
_と_@comment
_の両方が永続化されており、IDがそれぞれ1と2であると仮定します。以前と同じクラス。次に、_url_for
_は、構築しているURLにpost
を追加し、comment
も追加して、_[:admin, :post, :comment]
_になります。
次に、結合が発生し、_admin_post_comment_path
_のメソッドが生成されます。また、_@post
_と_@comment
_の両方がここに保持されるため、これらが渡され、次のメソッド呼び出しが発生します。
_admin_post_comment_path(@post, @comment)
_
これは(通常)このパスになります:
_/admin/posts/1/comments/2
_
配列形式のポリモーフィックルーティングは、_redirect_to
_、_link_to
_、および_form_for
_メソッドで使用できます。私が今覚えていない他の方法もおそらくそれを行うことができます...それは一般的にRailsで、通常はURLを受け取るものです。
Railsバージョンが2よりも大きいバージョンでハッシュを使用してURLを作成する必要はありません。これはかなり古い学校です。
代わりに、ポリモーフィックルーティングの新しい知識を試して、それを最大限に活用してください。
これは機能するはずです:
link_to "User Posts"、user_posts_path(@user)
詳細については、以下をご覧ください。
link_to
は url_for
を使用します polymorphic_url
を使用します。
polymorphic_url
:
ヘルパーメソッドを構築します 、アクティブレコードオブジェクトのクラス名を使用します
ヘルパーを呼び出す アクティブレコードオブジェクトを引数として使用
したがって、他の人が言ったように、あなたは使うべきです:
link_to 'User Posts', [@user, :posts]
パスは次のとおりです。
user_posts_path(@user)
^^^^ ^^^^^ ^^^^^
1 2 3
@user
のクラスはアクティブレコードであるためそれは良いヘルパーメソッドを構築します。
最新のRailsでネストされたリソースにリンクする方法は次のとおりです。
link_to「コメントを破棄」、post_comment_path(comment.post、comment)
注:これは部分的なものであるため、@
はありません。