Ruby on Rails:如何覆盖资源的“显示"路由? [英] Ruby on Rails: How to override the 'show' route of a resource?

查看:42
本文介绍了Ruby on Rails:如何覆盖资源的“显示"路由?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我有一条看起来像这样的路线:

Currently I have a route that looks like this:

resources :posts

我想覆盖显示"操作,以便我可以显示这样的网址:

I want to override the 'show' action so that I can display a url like this:

posts/:id/:slug

我目前可以通过添加自定义 match 路由来做到这一点:

I am currently able to do this by adding a custom match route:

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

但是,当我使用 link_to 帮助程序时,它不使用我的自定义显示路由.

However, when I use the link_to helper, it does not use my custom show route.

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

如何定义我的表演路线,以便我仍然可以使用 link_to 助手?

How can I define my show route so that I can still use the link_to helper?

更新:正如您在以下答案中所读到的,您可以覆盖显示"操作的路线,但这可能比它的价值更多.创建自定义路由更容易:

Update: As you can read in the following answers, you can override the route to the 'show' action, but it's probably more work than it's worth. It's easier to just create a custom route:

# 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) %>

推荐答案

您有两条路由指向 posts#show(您应该能够通过运行 rake routes),而您的链接使用了错误的链接.

You have two routes which point to posts#show (you should be able to confirm this by running rake routes), and your link is using the wrong one.

当您调用 link_to('show', post) 时,链接的 URL 是通过调用 url_for(post) 生成的,它(最终,在通过其他几个方法)调用 post_path(post).由于您对 resources(:posts) 的调用创建的 posts#show 路由名为 post,因此 posts#show 的路由code>post_path 生成.

When you call link_to('show', post) the URL of the link is generated by calling url_for(post) which (eventually, after passing through several other methods on the way) calls post_path(post). Since the route to posts#show that was created by your call to resources(:posts) is named post, that is the route that post_path generates.

您目前还具有不一致的显示、更新和销毁操作路线,这可能会在以后给您带来问题.

You also currently have inconsistent routes for the show, update and destroy actions which will probably cause you problems later on.

您可以通过将路由更改为以下内容来解决此问题:

You can fix this by changing your routes to the following:

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 作为单个参数需要建立一个帖子的路径.您的自定义路由需要两个参数,一个 id 和一个 slug.所以现在您的链接代码需要如下所示:

Unfortunately you still can't use link_to('show', post) just yet, because it relies on being able to use post.to_param as the single argument needed to build a path to a post. Your custom route requires two arguments, an id and a slug. So now your link code will need to look like this:

link_to 'show', post_path(post.id, post.slug)

您可以通过在 app/helpers/posts_helper.rb 中定义自己的 post_pathpost_url 助手来解决这个问题:

You can get around that problem by defining your own post_path and post_url helpers in 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

这意味着我们终于可以使用了:

Which means we're finally able to use:

link_to 'show', post

<小时>

如果这一切看起来工作量太大,一个常见的替代方法是使用看起来更像 posts/:id-:slug 的 URL,在这种情况下,您可以坚持使用标准的 RESTful 路由和只需覆盖 Post 类中的 to_param 方法:


If that all seems like too much work, a common alternative is to use URLs that look more like posts/:id-:slug, in which case you can stick with the standard RESTful routes and just override the to_param method in your Post class:

def to_param
  "#{id}-#{slug}"
end

您还需要做一些工作,将 params[:id] 拆分为 ID 和 slug,然后才能在节目中查找相关实例、编辑、更新并销毁控制器操作.

You'll also need to do a little bit of work splitting up params[:id] into an ID and a slug before you can look up the relevant instance in your show, edit, update and destroy controller actions.

这篇关于Ruby on Rails:如何覆盖资源的“显示"路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆