0

仅限 Ruby on Rails 4.2+,拜托!

我一直在寻找有关如何在 Rails 中使 URL 更漂亮的提示,但我正在努力寻找我喜欢的解决方案。

我想要的是:

假设示例:给定主题、课程等具有一堆字段(包括 URL 友好的 slug)的模型,我希望能够

# ../routes.rb
# Match urls of the form /edu/material-engineering. These are read-only
# public URLs, not resources.
get 'edu/:slug', to: 'education#topic', as: :learn_topic
get 'edu/course/:id/slug', to: 'education#course', as: :learn_course
...

# I also have admin-only resource-oriented controllers for managing
# the content, but that's separate.
namespace :admin do
  resource :topic
  resource :course
  ...
end

# ../some_view.html.erb
# Generate URLS like this:
<%= link_to topic.name, learn_topic_path(topic) %>
<%= link_to course.name, learn_course_path(course) %>

我不想要的:

  • 胡闹to_param。这是一个肮脏的黑客,完全打破了关注点分离。
  • 资源/RESTful 路由。除了“读取”之外,这里没有 CRUD 操作。
  • link_to 'text', course_path(id: course.id, slug: course.slug). 这完全违背了不需要视图知道为课程生成 URL 所需的参数的目的。
  • 编辑:我知道 FriendlyId 存在,但我只是想了解这种事情是如何完成的以及机制是什么,所以这不是现在的解决方案。

必须有一种方法来告诉命名的路由助手从主题模型对象topic_path(topic)中获取路由中所需的参数(例如,:slug:id,等等)。

有人知道吗?谢谢!

4

2 回答 2

1

我能想到的最好的方法:只需*_path用我自己的实现覆盖助手。

如果您知道一种使默认助手工作的方法,请加入!

这个问题归结为一个问题:自动生成的*_path助手*_url并没有给我想要的灵活性。我想让他们做的是微不足道的,所以没有其他选择,我可以自己写:

module ApplicationHelper
  def learn_topic_path(topic)
    "/edu/#{topic.slug}"
  end

  ...
end

编写一些 _path/_url 帮助程序覆盖可以避免各种复杂性,并允许您避开 to_param,避免包含新插件等。

人们可能会更进一步,从已知的路由规则生成路由的静态组件,并推断如果动态段名称与模型属性名称一致,则需要从模型中提取哪些属性,但这开始一旦你做了更复杂的事情或添加多个模型(例如,'edu/:topic_slug/:course_slug'),就会崩溃。

这样做的最大缺点是,您现在每次更改路由时都必须在两个地方更新路由:路由定义本身routes.rb以及 中的相应路由助手application_helper.rb。我现在可以忍受。

于 2015-02-23T05:55:42.603 回答
0

您可以使用 FriendlyId gem 来实现这一点。

这是链接:

https://github.com/norman/friendly_id/blob/master/README.md

如果您有任何问题,请告诉我。

于 2015-02-22T02:08:14.487 回答