17

現在、次のようなルートがあります。

resources :posts

「表示」アクションをオーバーライドして、次のような URL を表示できるようにします。

posts/:id/:slug

現在、カスタムmatchルートを追加することでこれを行うことができます:

resources :posts
match 'posts/:id/:slug' => 'posts#show'

ただし、link_toヘルパーを使用すると、カスタム ショー ルートが使用されません。

<%= link_to 'show', post %>  # renders /posts/123

link_toヘルパーを引き続き使用できるように、show ルートを定義するにはどうすればよいですか?

更新:次の回答を読むとわかるように、「表示」アクションへのルートをオーバーライドできますが、おそらくそれ以上の作業が必要です。カスタム ルートを作成する方が簡単です。

# config/routes.rb
match 'posts/:id/:slug' => 'posts#show', as: 'post_seo'

# app/views/posts/index.html.erb
<%= link_to post.title, post_seo_path(post.id, post.slug) %>
4

3 に答える 3

40

を指している 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 つの引数が必要です。したがって、リンク コードは次のようになります。idslug

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 とスラッグに分割する少しの作業を行う必要があります。

于 2012-07-20T00:36:52.967 に答える
2
resources :posts, except: :show do
    get ":slug" => :show, as: "", on: :member
end

ヘルパーを定義する

  def post_path post
     "/posts/#{post.id}/#{post.slug}"
  end
于 2012-07-20T01:18:45.980 に答える
0

デシベル/移行/add_slug_to_articles.rb

add_column :articles, :slug, :string
add_index :articles, :slug

models/article.rb

class Article < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged

  def should_generate_new_friendly_id?
    new_record?
  end
end

または...

class Article < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :history
end

http://railscasts.com/episodes/314-pretty-urls-with-friendlyid

https://github.com/norman/friendly_id

于 2012-07-19T23:47:47.257 に答える