How to pass params to a block in Rails routes?

可紊 提交于 2020-01-22 16:38:30

问题


I am using Rails 3. And I'm wondering how to pass params to some blocks in routes.rb.

What I'm trying to do is to make a catch all route, that check from slugs database the model name of it by the id.

After getting the model name i pluralize it to get the controller name.

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

The table slugs

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

When I try to access some pages like /4d2c7de0c5abe7f8a9000007 I got this error:

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)

The expected is to point to posts#view with iid: 4d2c7de0c5abe7f8a9000007


回答1:


proc returns a Proc, but match is expecting a string. You could try adding .call to have the proc return its value. Though I'm not sure if this will end up calling the proc each time or only when routes is loaded...

EDIT

Seems I was way off-base with my earlier response and comments. Maybe something like this?:

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

Though this really ought to be defined in a library and included. Perhaps someone knows a better way?




回答2:


Putting this in your routes seems really hacky. I would recommend creating a Slugs controller, passing this task onto that, and redirecting to the appropriate controller from there. Assuming your other pages use standard RESTful routes, you could do something like this:

Change route to this:

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

Slugs controller:

def show
  slug = Slug.find_by_iid(params[:id])

  redirect_to send("#{slug.model}_url", params[:id])
end


来源:https://stackoverflow.com/questions/4663218/how-to-pass-params-to-a-block-in-rails-routes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!