【问题标题】:How to pass params to a block in Rails routes?如何将参数传递给 Rails 路线中的块?
【发布时间】:2011-06-07 11:40:20
【问题描述】:

我正在使用 Rails 3。我想知道如何将参数传递给 routes.rb 中的某些块。

我要做的是创建一个catch all 路由,从slugs 数据库中通过id 检查它的模型名称。

在获得model name 后,我将其复数以获取控制器名称。

match '/:id', :controller => proc { Slug.find_by_iid(params[:id]).model.pluralize }, :action => :show

slugs

model    iid
-----    -----
post     4d2c7de0c5abe7f8a9000007
item     4d2c7de0c5abe7f809000004

当我尝试访问像 /4d2c7de0c5abe7f8a9000007 这样的页面时,我收到了这个错误:

Started GET "/4d2c7de0c5abe7f8a9000007" for
127.0.0.1 at 2011-01-12 00:04:31 +0200

ActionController::RoutingError (wrong constant name #<Proc:0x0000010337c310@):

Rendered /Users/amr/.rvm/gems/ruby-1.9.2-p136@rails3/gems/actionpack-3.0.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.2ms)

预期是指向帖子#view with iid: 4d2c7de0c5abe7f8a9000007

【问题讨论】:

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


    【解决方案1】:

    proc 返回一个 Proc,但 match 需要一个字符串。您可以尝试添加 .call 让 proc 返回其值。虽然我不确定这是否会最终调用 proc 每次还是仅在加载 routes 时...

    编辑

    我之前的回复和 cmets 似乎有点离谱。也许是这样的?:

    match '/:id', :to => proc { |env|
      id = env["action_dispatch.request.path_parameters"][:id]
      model = Slug.find_by_iid(id).model
      controller = [model.pluralize.camelize,"Controller"].join.constantize
      controller.action("show").call(env)
    }
    

    虽然这确实应该在库中定义并包含在内。也许有人知道更好的方法?

    【讨论】:

    • 我可以像:controller =&gt; Slug.find_by_iid(params[:id]).model.pluralize 这样删除proc,但问题仍然是如何获得params[:id] 值。当我尝试运行该应用程序时,它会在 ': undefined local variable or method params' for #&lt;ActionDispatch::Routing::Mapper:0x000001031a2af8&gt; (NameError) 中向我抛出错误 ../config/routes.rb:6:in block
    • 当我做到controller =&gt; proc { Slug.find_by_iid(params[:id]).model.pluralize }.call 时,它把/config/routes.rb:6:in block(2 个级别)扔到了':未定义的局部变量或方法params' for #&lt;ActionDispatch::Routing::Mapper:0x000001030c9b40&gt; (NameError) ALSO!
    • 啊,我错过了那里的params。我认为这不起作用——params 设置在控制器中,而不是路由引擎中。看看这里的答案:stackoverflow.com/questions/2596312/…
    • 谢谢。我之前已经看过了,不是我要找的解决方案!
    • 此解决方案的演变。 stackoverflow.com/questions/5641786/…
    【解决方案2】:

    把它放在你的路线中似乎真的很老套。我建议创建一个 Slugs 控制器,将此任务传递给该控制器,然后从那里重定向到适当的控制器。假设您的其他页面使用标准 RESTful 路由,您可以执行以下操作:

    改变路线:

    match '/:id', :controller => :slugs, :action => :show
    

    蛞蝓控制器:

    def show
      slug = Slug.find_by_iid(params[:id])
    
      redirect_to send("#{slug.model}_url", params[:id])
    end
    

    【讨论】:

    • 我不想做重定向老兄!我只是想让应用程序了解我的 slug,并加载相关模型。就像在 facebook.com 和 quora.com 中一样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2013-04-28
    • 1970-01-01
    相关资源
    最近更新 更多