如何将params传递给Rails路由中的块?

我正在使用Rails 3.我想知道如何将params传递给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) 

预计是指向post#view with iid:4d2c7de0c5abe7f8a9000007

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

编辑

似乎我对我之前的回复和评论偏离了基础。 也许是这样的?:

 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) } 

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

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

改变路线:

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

Slugs控制器:

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