ruby on rails - rout.rb - соответствует расширению файла, если в имени файла существует несколько периодов - PullRequest
1 голос
/ 21 марта 2011

Я создал контроллер маршрута плюс для выполнения динамического CSS в ruby ​​на рельсах согласно инструкциям здесь:

http://www.misuse.org/science/2006/09/26/dynamic-css-in-ruby-on-rails/

Потребовалось внести некоторые изменения, чтобы учесть более новую версию ruby ​​на рельсах, но проблема возникает с записью маршрутов. Оригинальная запись была такой:

  # dynamic CSS (stylesheets)
  map.connect 'rcss/:rcssfile',
    :controller => 'rcss',
    :action => 'rcss'

Это не работает с более новой версией RoR, и я нашел это решение для работы:

  # dynamic CSS (stylesheets)
  map.connect 'rcss/:rcssfile.css',
    :controller => 'rcss',
    :action => 'rcss'

Однако, теперь я был огорчен тем, что не смог получить универсальный обработчик расширения типа файла. Запрос должен иметь расширение .css. Играя с этим дальше, я придумал это:

  # dynamic CSS (stylesheets)
  map.connect 'rcss/:rcssfile.:format',
    :controller => 'rcss',
    :action => 'rcss'

Так что это намного лучше. Теперь я мог бы потенциально запросить файл, заканчивающийся на .foobar или что-то еще, и сопоставить его с обработчиком. Не обязательно, но это больше касается понимания всего.

Итак, я попытался создать файл, похожий на «foo.net.rcss». Теперь может показаться, что первая точка все испортила. msgstr "нет маршрутов, соответствующих rcss / foo.net.css". Мои вопросы следующие:

  1. Как мне сопоставить любое имя файла и любое расширение независимо от того, сколько точек в имени файла?

  2. Почему первый пример не работает в более поздних версиях RoR?

  3. Почему несколько точек портят спичку?

Заранее спасибо за любую помощь.

------- обновление -------

Я использую Rails 3.0.5. Согласно еще одному исследованию, я могу сократить синтаксис до:

match 'rcss/:rcssfile', :to => 'rcss#rcss'

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

match 'rcss/:rcssfile:.:format', :to => 'rcss#rcss'

Это также работает так же, как мой предыдущий пример # 3, однако все еще имеет проблему несоответствия файла с несколькими периодами.

Ответы [ 3 ]

4 голосов
/ 29 марта 2011

Казалось бы, при маркировке стандарта ": paramater" особое внимание уделяется символу точки. «: параметр» будет соответствовать пути с одним периодом, «: параметр.: расширение» будет соответствовать пути с двумя периодами, но расширение: будет только тем, что находится между двумя периодами и т. д.

Способом обойти это является использование так называемой "маршрутизации", в которой вместо двоеточия используется звездочка:

match 'rcss/*rcssfile', :to => 'rcss#rcss'

Единственное предостережение в том, что это будет соответствовать НИЧЕМ после звездочки, включая подкаталоги. Таким образом, вы хотите убедиться, что это случайно не предоставит какие-либо защищенные файлы или непреднамеренно сделает вещи непреднамеренными.

1 голос
/ 21 марта 2011

Использовать регулярное выражение для соответствия имени файла?

map.connect 'rcss/:rcssfile',
  :controller => 'rcss',
  :action => 'rcss',
  :requirements => {:rcssfile => /.+\.rcss/ }

Это будет соответствовать (что угодно) .rcss - вы можете настроить регулярное выражение для различных суффиксов.

0 голосов
/ 29 сентября 2015

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

get '/uploads/:basename.:extenstion', to: 'controller#action', basename: /.*(?=\.[\w\d]+$)/
...