Как я могу маршрутизировать на разные контроллеры с одинаковым форматом URL в Rails? - PullRequest
1 голос
/ 24 января 2011

У меня есть две разные модели, которые могут отображаться в категории.В моем rout.rb я хотел бы иметь что-то вроде этого:

ActionController::Routing::Routes.draw do |map|
  map.top_list ':category/:foo', :controller => 'foo', :action => 'show'
  map.top_list ':category/:bar', :controller => 'bar', :action => 'show'
end

Это прекрасно работает, когда я загружаю URL-адрес типа "/ some-category-name / some-foo-name ", где" some-foo-name "может быть загружено FooController следующим образом:

class FooController < ApplicationController
  def show
    @foo = Foo.find_by_url! params[:foo]
  end
end

Но когда я пытаюсь запросить Bar, например" / some-category-name-name / some-bar-name ", я получаю" ActiveRecord :: RecordNotFound в FooController # show ".Я знаю, что могу решить эту проблему, требуя, чтобы все имена Foo начинались с «foo-», а все имена баров начинались с «bar-», а затем определяли маршруты следующим образом:

ActionController::Routing::Routes.draw do |map|
  map.top_list ':category/:foo', :controller => 'foo', :action => 'show', :requirements => { :name => /^foo-/ }
  map.top_list ':category/:bar', :controller => 'bar', :action => 'show', :requirements => { :name => /^bar-/ }
end

Но с применением этого ограниченияпо именам довольно неоптимальный.Я обнаружил следующее, которое выглядит так: может работать на меня: Различные маршруты, но с использованием одного и того же контроллера для подклассов модели в Rails .Тем не менее, я не совсем следую примеру, поэтому я не знаю, решит ли это мою проблему.Также не очень хорошо, что мои Foo и BarController должны были бы наследовать от CategoryController.

Одна мысль, которая пришла мне в голову, это то, что я могу попытаться найти Foo, а затем вернуться к BarController, если это не удастся.Я легко могу сделать это в FooController и перенаправить на BarController, но это не совсем нормально, так как все запросы на Bars будут регистрироваться как FooController # show в журнале Rails.Однако, если бы я мог как-то настроить маршруты для вызова метода, чтобы определить, к чему направлять, основываясь на базовом имени URL, я мог бы получить поведение, которое мне нужно;Например,

ActionController::Routing::Routes.draw do |map|
  is_a_foo = Proc.new {|name| Foo.find_by_url! name && true }

  map.top_list ':category/:foo', :controller => 'foo', :action => 'show', :requirements => { :name => is_a_foo }
  map.top_list ':category/:bar', :controller => 'bar', :action => 'show'
end

Есть ли способ сделать это в стандартном болоте Rails 2?

Ответы [ 2 ]

2 голосов
/ 25 января 2011

Я закончил тем, что написал небольшой плагин Rails, который позволяет мне писать маршрут следующим образом:

map.with_options :category => /[-A-Za-z0-9]+/ do |m|
  # Since both foos and bars can appear under category, we define a route for foo that only matches when
  # the foo can be found in the database, then fall back to the bar route
  m.foo ':category/:foo', :controller => 'foo', :action => 'show', :conditions => {
      :url => { :find_by_url => Foo }
  }
  m.bar ':category/:bar', :controller => 'bar', :action => 'show'
end

Пока я не получу разрешение на открытие исходного кода, я должен оставить реализацию в качестве упражнения длячитатель, но вот как я туда попал:

  1. Рельсы для исправления обезьян: расширение маршрутов # 2
  2. Под капотом: распознавание маршрута вRails
  3. Полное руководство по плагинам Rails: Часть II

Я дополню этот ответ ссылкой на github, когда смогу.:)

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

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

Было бы лучше использовать что-то вроде этого:

map.top_list ':category/foo/:foo', :controller => 'foo', :action => 'show', :requirements => { :name => is_a_foo }
map.top_list ':category/bar/:bar', :controller => 'bar', :action => 'show'

Поскольку в предоставленных маршрутах вы каждый раз задаете два параметра.Неважно, что вы называете их по-другому.Это просто соответствует обоим.

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