开发者

How to pass params to a block in Rails routes?

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 e开发者_StackOverflowrror:

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


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?


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜