を指している 2 つのルートがありposts#show
( を実行してこれを確認できるはずですrake routes
)、リンクが間違ったルートを使用しています。
link_to('show', post)
リンクの URL を呼び出すと、 url_for(post)
which を呼び出すことによって生成されます (最終的に、途中で他のいくつかのメソッドを通過した後) 呼び出しますpost_path(post)
。posts#show
への呼び出しによって作成されたへのルートのresources(:posts)
名前post
は であるため、それが生成されるルートですpost_path
。
また、現在、show、update、および destroy アクションのルートが一貫していないため、後で問題が発生する可能性があります。
これを修正するには、ルートを次のように変更します。
resources :posts, :except => ['show', 'update', 'destroy']
get 'posts/:id/:slug' => 'posts#show', :as => 'post'
put 'posts/:id/:slug' => 'posts#update'
delete 'posts/:id/:slug' => 'posts#destroy'
残念ながら、投稿へのパスを構築するために必要な単一の引数としてlink_to('show', post)
使用できることに依存しているため、まだ使用することはできません。post.to_param
カスタム ルートには、 anと a の2 つの引数が必要です。したがって、リンク コードは次のようになります。id
slug
link_to 'show', post_path(post.id, post.slug)
post_path
で独自のpost_url
ヘルパーを定義することで、この問題を回避できますapp/helpers/posts_helper.rb
。
module PostsHelper
def post_path(post, options={})
post_url(post, options.merge(:only_path => true))
end
def post_url(post, options={})
url_for(options.merge(:controller => 'posts', :action => 'show',
:id => post.id, :slug => post.slug))
end
end
つまり、最終的に使用できるようになりました。
link_to 'show', post
それが面倒だと思われる場合、一般的な代替手段は、より似た URL を使用することですposts/:id-:slug
。この場合、標準の RESTful ルートを使用して、クラス内のto_param
メソッドをオーバーライドするだけです。Post
def to_param
"#{id}-#{slug}"
end
params[:id]
また、コントローラ アクションの表示、編集、更新、および破棄で関連するインスタンスを検索する前に、ID とスラッグに分割する少しの作業を行う必要があります。