【问题标题】:Rails 4 custom named route not calling correct property of modelRails 4自定义命名路由未调用模型的正确属性
【发布时间】:2015-05-25 15:18:15
【问题描述】:

根据http://edgeguides.rubyonrails.org/routing.html#overriding-named-route-parameters,我正在定义一个带有自定义命名路由参数的路由,而不是:id,以创建友好的URL。 routes.rb 看起来像:

resources :spaces, param: :name

运行 rake routes 确实给出了带有动态段的正确路径:

space GET    /spaces/:name(.:format)                spaces#show

但使用space_path 仍会尝试检索 ID:

irb(main):009:0> app.space_path space
=> "/spaces/1"

是否应该给出“/spaces/foo”(假设带有id=1 的空间有name=foo

我可以明确地这样做:

irb(main):009:0> app.space_path space.name
=> "/spaces/foo"

但随后我失去了动态路径的全部意义,我的所有观点都变得更加脆弱。动态路径是否应该无法识别要检索的属性?

我知道我可以在模型中覆盖to_params,但同样,这不是让模型变脆吗?动态路径不应该识别动态段的名称并从模型中检索正确的属性吗?

【问题讨论】:

    标签: ruby-on-rails rails-routing


    【解决方案1】:

    app.space_path 将采用您提供的第一个参数并将其替换为:name。如果参数是一个 ActiveModel 实例,它将在其上调用 to_param,除非您覆盖它,否则它将返回 id 属性的值——在本例中为 1,而不是 foo

    如果您希望app.space_path(space) 返回/spaces/foo,您需要覆盖Space#to_param

    class Space < ActiveRecord::Base
      # ...
      def to_param
        name
      end
    end
    

    您的路由中的:name 唯一要做的就是确定params 中该值的键在您的控制器中,即如果请求/spaces/foo,则params[:name] 将是"foo"

    【讨论】:

    • 所以路由中的:name 只决定了放在参数中的内容,即 URL->params,而不是 URL 构造?所以如果我有/spaces/:foo/:bar/:zed,它不会自动从我的Space 模型中提取属性foobarzed?我需要明确地做path(space.foo, space.bar, space.zed)?
    • 没错。你可以这样做path(*space.values_at(:foo, :bar, :zed)),但那样你并没有真正得到任何东西。
    • 很可惜。如果它可以双向切割,那将是非常令人印象深刻的。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    相关资源
    最近更新 更多