我正在使用Rails 3.我想知道如何将params传递给routes.rb
中的某些块。
我要做的是制作catch all
路线,从slugs
数据库检查ID的型号名称。
获取model name
i后,将其复数以获取控制器名称。
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
答案 0 :(得分:8)
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)
}
虽然这确实应该在图书馆中定义并包含在内。也许有人知道更好的方法吗?
答案 1 :(得分:0)
把这个放在你的路线上似乎真的很烦人。我建议创建一个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