Проблема с маршрутизацией.Почему это не работает, или как я могу иметь несколько почти идентичных ограничений в Rails 3.1? - PullRequest
2 голосов
/ 07 октября 2011

У меня есть несколько публикаций (сообщений), которые относятся к типу и категории, и я хочу, чтобы маршруты были такими:

  • / some-type-slug
  • /some-type-slug / some-category-slug
  • / some-category-slug

, которые все указывают на публикации # index, где я выполняю всю фильтрацию

Пока я пробовал только с типом и необязательной категорией, он прекрасно работал с:

scope ':type', :constraints => lambda{|req| PublicationType.all.map(&:slug).include?(req.params[:type].singularize) } do
  match 'new'          => 'publications#new'
  match '(/:category)' => 'publications#index'
end

Но когда я добавил тот же бит кода о категориях, и я попытался перейти к "/ some-category"это закончилось, просто не работает:

match ':category' => 'publications#index', :constraints => lambda{|req| Category.all.map(&:slug).include?(req.params[:category].singularize) }

приводит к:

NoMethodError in PublicationsController#index

undefined method `singularize' for nil:NilClass

Parameters:

{"type"=>"some-category-slug"}

Хорошо, так что NoMethodError выбрасывается, потому что params [: category] равен нулю.И это потому, что часть: category URL-адреса только что была «украдена» предыдущим определением маршрута: params [: type] устанавливается с частью: category URL-адреса.

Так что мне интересно, если этоошибка в маршрутизаторе Rails или я просто пытаюсь зайти слишком далеко.И если я хочу знать, какие у меня есть другие варианты для достижения того же результата.

Спасибо!

1 Ответ

3 голосов
/ 08 октября 2011

Я понимаю, что вы хотите сделать, но я думаю, что вы находитесь на опасной земле, пытаясь подобрать маршруты, подобные этой.

То, что вы делаете, также может быть достигнуто так.

match ":slug" => "slugs#show"

class SlugsController

  def show
    if type = PublicationType.find_by_slug(params[:slug])
      ...
    elsif category = Category.find_by_slug(params[:slug])
      ...
    else
      render_404
    end
  end
end

(см. Этот ответ для большого обсуждения , как сделать 404 )

Это может показаться чрезмерным но это эффективно то, что вы делаете в любом случае.

Вы просто делаете это с лямбдами в файле маршрутов.

Я предлагаю вам пересмотреть свою стратегию URL.

/cat/some-slug
/type/some-slug

не так уж и плохо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...