ruby-on-rails – Ruby on Rails:如何覆盖资源的’show’路由?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Ruby on Rails:如何覆盖资源的’show’路由?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
目前我有一条如下所示的路线:
resources :posts

我想覆盖’show’动作,以便我可以显示一个这样的URL:

posts/:id/:slug

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

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

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

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

我如何定义我的show路由,以便我仍然可以使用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) %>

解决方法

你有两条路线指向#show(你应该可以通过运行rake路线来确认),你的链接使用错误的路线.

当你调用link_to(‘show’,post)链接的URL是通过调用url_for(post)生成的(最后,在通过其他几种方法之后)调用post_path(post).由于通过调用资源(:posts)创建的帖子#show的路由被命名为post,这就是post_path生成的路由.

您目前还有不一致的路线,显示,更新和销毁行为,这可能会导致您以后出现问题.

您可以通过将路由更改为以下方法解决此问题:

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.所以现在您的链接代码将需要如下所示:

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

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

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

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

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

您还需要做一些工作,将params [:id]分解成一个ID和一个插件,然后才能在显示,编辑,更新和销毁控制器操作中查找相关实例.

猜你在找的Ruby相关文章