Пустые маршрутные глобусы в Рельс 3 - PullRequest
1 голос
/ 13 декабря 2011

Я обновляю Rails 2 до 3.1, и у меня возникли некоторые проблемы с маршрутами. У нас в Rails 2 работали глобальные маршруты, которые выглядели так:

map.connect '/foo/*bar', :controller => 'foo', :action => 'index'

GET для '/ foo / one / two' даст следующие параметры на стороне контроллера:

{
  :controller => 'foo',
  :action => 'index',
  :bar => ['one, 'two']
}

Пустые глобусы были в порядке, поэтому мы могли бы также выполнить GET '/ foo' и получить:

{
  :controller => 'foo',
  :action => 'index',
  :bar => []
}

При обновлении до Rails 3.1 есть несколько отличий:

match '/foo/*bar', :to => 'foo#index'

Сегментированный сегмент маршрута представлен в виде строки, а не массива, но я рассмотрел это в своем коде. Нет проблем там. GET '/ foo / one / two' дает:

{
  :controller => 'foo',
  :action => 'index',
  :bar => 'one/two'
}

Проблема возникает, когда у меня ничего нет в сегменте глобуса. GET '/ foo' больше не маршрутизируется, и если я пытаюсь сгенерировать URL из параметров, он не может генерировать. По сути, если params [: bar] - пустая строка, она просто не может маршрутизироваться.

Это неудобно в моем приложении, так как создание разумных URL зависит от поведения Rails 2.3. У нас также есть случаи, когда шар находится в середине пути:

match '/foo/*bar/show', :to => 'foo#show'

Это означает, что у нас были такие пути, как:

/foo/one/two/show
/foo//show

Есть ли способ заставить механизм маршрутизации обрабатывать пустые строки, как это было в Rails 2.3? Я попытался добавить дополнительные маршруты для версии empty-glob, которая работает в случае простого трейлинг-глоба, но в случае, когда glob находится в середине пути, это не так.

1 Ответ

3 голосов
/ 14 декабря 2011

Я получаю тесты, проходящие по этим маршрутам:

Your::Application.routes.draw do
  match '/foo/', :to => 'foo#index', :bar => ''
  match '/foo//show', :to => 'foo#show', :bar => ''
  match '/foo/*bar/show', :to => 'foo#show'
  match '/foo/*bar', :to => 'foo#index'
end

Последовательность важна!

Неоднозначность : означает ли / foo / show "показать foo-index" или сделать "index for bar = show"?

Тест:

require_relative '../test_helper'

class FooRoutingTest < ActionController::TestCase
  test 'root index' do
    assert_recognizes({:controller => 'foo', :action => 'index', :bar => ''}, '/foo')
    assert_recognizes({:controller => 'foo', :action => 'index', :bar => ''}, '/foo/')
  end

  test 'root show' do
    assert_recognizes({:controller => 'foo', :action => 'show', :bar => ''}, '/foo/show')
    assert_recognizes({:controller => 'foo', :action => 'show', :bar => ''}, '/foo//show')
  end

  test 'wildcard index' do
    assert_recognizes({:controller => 'foo', :action => 'index', :bar => 'hello'}, '/foo/hello')
    assert_recognizes({:controller => 'foo', :action => 'index', :bar => 'hello/more'},'/foo/hello/more') 
  end

  test 'wildcard show' do 
    assert_recognizes({:controller => 'foo', :action => 'show', :bar => 'wow'}, '/foo/wow/show')
    assert_recognizes({:controller => 'foo', :action => 'show', :bar => 'wow/more'}, '/foo/wow/more/show')
  end
end
...