【问题标题】:Rails named route with dynamic segments URL generation from modelRails 命名路由,从模型生成动态段 URL
【发布时间】:2015-02-22 01:48:16
【问题描述】:

仅限 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 ,无论其他)来自主题模型对象。

有人知道吗?谢谢!

【问题讨论】:

  • friendly_id 它自己使用to_param,你为什么认为这很糟糕?你告诉模型如何在 url 中表示它自己,你认为这是一个 hack,但我认为它是反映整个系统的最干净的方式
  • @MohammadAbuShady, to_param 的功能等同于在模型上使用 to_partial 方法,该方法会为模型吐出 HTML 表示。我们将模型与视图分开是有原因的,而 URL 只是另一种视图。没有理由让模型任何知道应用程序的路由/URL 方案是什么。
  • 好吧,如果我想严格(或愚蠢)并从另一边看,我也可以说路由不应该知道路由使用的属性名称和顺序,所以我不能说会以任何一种方式发生真正的分离,无论如何我不知道你想要的是否可能,你应该找到url_for 的实际实现方式,以及它的行为方式一个 activerecord 对象被传递给它,我很想知道你最后发现了什么,祝你好运,
  • 我会继续挖掘,如果我弄明白了,我一定会回复的。至于您的观点,这似乎就像在说“我也可以说视图不应该知道以什么顺序将哪些模型字段放在页面上”......这显然没有意义。这就是视图的目的,或者在 URL 的情况下是路由方案。 View->Model 是一个观察者->被观察的关系。依赖项应该只有一种方式。
  • 我想这是有道理的,你可以问friendly_id的人,他们可能已经对此做了很多挖掘,有人可能会提供帮助。

标签: ruby-on-rails ruby-on-rails-4 routing ruby-on-rails-4.2 named-routing


【解决方案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 中的相应路由助手。我现在可以忍受。

【讨论】:

    【解决方案2】:

    您可以使用 FriendlyId gem 来实现。

    这是链接:

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

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

    【讨论】:

    • 感谢@neo,但我试图了解如何使用香草Rails 来做到这一点,而不仅仅是寻找别人的解决方案。
    • 如果你想知道它是如何工作的,你可以浏览代码库。
    • 我很欣赏这个想法,但我有。 FriendlyId a) 非常复杂(包括为蛞蝓引入新模型)并且 b) 试图解决比我感兴趣的更多的问题。
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 2018-12-15
    • 1970-01-01
    相关资源
    最近更新 更多