Как передать параметры в блок в маршрутах Rails? - PullRequest
2 голосов
/ 12 января 2011

Я использую Rails 3. И мне интересно, как передать параметры в некоторые блоки в routes.rb.

Я пытаюсь создать маршрут catch all, который проверяет из базы данных slugs название модели по идентификатору.

Получив 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 с iid: 4d2c7de0c5abe7f8a9000007

Ответы [ 2 ]

8 голосов
/ 12 января 2011

proc возвращает Proc, но match ожидает строку. Вы можете попробовать добавить .call, чтобы proc возвращал свое значение. Хотя я не уверен, что это вызовет процедуру каждый раз или только когда загружено routes ...

EDIT

Кажется, я был совершенно не в своем вкусе с моими предыдущими ответами и комментариями. Может быть как то так? * 1011

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

Хотя это действительно должно быть определено в библиотеке и включено. Возможно, кто-нибудь знает лучший способ?

0 голосов
/ 12 января 2011

Поместить это в ваши маршруты кажется действительно глупым.Я бы порекомендовал создать контроллер 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...