Rails:如何使用Rails内置的“资源”创建Stackoverflow样式的URL?

时间:2013-05-27 03:13:57

标签: ruby-on-rails-3.2 rails-routing

Stackoverflow网址就像这样:

http://stackoverflow.com/users/12345/name-of-user

它具有真正RESTful路由的所有属性:

:resource_name/:resource_id

但它在name段之后也有:resource_id部分。我知道如何使用非资源路由的Rails实现它。但是可以使用其内置的默认resources :user方法实现相同的URL吗?

默认情况下,第三段是Rails中的格式:

/users/:id(.:format)      users#show

3 个答案:

答案 0 :(得分:1)

我知道这是一个古老的问题,但似乎仍然有一些兴趣。所以我会发布我想出的内容。

我不确定你想要多大程度上有足够的资源,但这种情况很有效:

resources :articles do
  member do
    get '*slug', to: 'articles#show', as: 'slugged'
  end
end

这也有效:

resources :articles do
  member do
    get ':slug', to: 'articles#show', as: 'slugged'
  end
end

在这两种情况下,您都可以使用

 <%= link_to slugged_article_path(article, article.title.parameterize) %>

在您的视图中(您可能希望在模型中为slug定义虚拟属性,而不是在视图中使用article.title.parameterize动态构建它)。

请注意,到目前为止,如果您在浏览器中输入slug,Rails不会抱怨。

我个人觉得这个资源丰富的方法有点冗长,因为我只对显示动作(这是常规用户或搜索引擎机器人可能看到的唯一的那些)感兴趣,所以我发现它更简单简单地做:

resources :articles
get 'articles/:id/:slug', to: 'articles#show', as: 'slugged_article'

答案 1 :(得分:0)

您可以使用FriendlyId。 Github中有一个存储库,并且有详细记录。 Ryan bates还在RailsCasts

中制作了一个非常好的视频教程

答案 2 :(得分:0)

假设你有一个控制器questions_controller

在routes.rb中:

get 'questions/:id/:slug', to: 'questions#show'

在questions_controller.rb中:

def show
  @question = Question.find(params[:id])
  if request.path != question_path(@question)
    redirect_to @question, status: :moved_permanently
    return
  end
...
end

问题.rb:

def to_param
  "#{id}/#{name.parameterize}"
end

就是这样。所有生成的路径都将包含slug,如果尝试访问/questions/42/questions/42/incorrect-slug,则会重定向。