2011-07-20 1 views
1

У меня есть Contact модели, которую я хочу, чтобы получить доступ через слизняк в URL, так что я отменяю to_param как так:Маршрутов и функция маршрутизации для успокоительных ресурсов с пользовательскими слизнями

def to_param 
    "#{self.id}-#{full_name.parameterize}" 
end 

Я использую стандарт, остаточные ресурсы:

resources :contact 

Это работает как ожидалось. Помощники пути возвращают измененные URL-адреса. И URL-адреса правильно перенаправляются на контроллер. Все идет нормально.

Проблема в том, что, хотя слизень маршрутизирован правильно, обновление спецификаций маршрутизации для отражения изменений приводит к сбою спецификации.

E.g. эта спецификация не может:

get("/contacts/1-john-smith").should route_to("contacts#show", :id => "1") 

Оригинальная версия проходит:

get("/contacts/1").should route_to("contacts#show", :id => "1") 

Что-то не совсем добавить здесь. Почему спецификация не работает, когда URL-адрес правильно разрешен в браузере? И как получилось изменение to_param не нарушает исходный URL?

Что еще более важно, как изменить объявление маршрутизации так, чтобы спецификация прошла? Могу ли я сделать это с помощью декларации resources? или я должен определить эти маршруты вручную?

ответ

1

В вашем get вы передаете id из "1-john-smith", так что ваш контроллер получит. Изменение спецификации к этому:

get("/contacts/1-john-smith").should route_to("contacts#show", 
    :id => "1-john-smith") 

код маршрутизации равнодушен к пробкового функции, которые вы добавили, и он не будет знать, чтобы сдирать определенные части параметра id. Магия в основном в ActiveRecord::Base#find, потому что это:

Contacts.find "1-john-smith" 

работает так же, как это:

Contacts.find "1" 
+0

Совершенно верно ~ спасибо! Я искал способ определения маршрута, чтобы я мог анализировать числовой идентификатор из пули, прежде чем передавать его контроллеру, но поскольку '# find' делает их эквивалентными в любом случае, в этом случае это не имеет большого значения. –

+0

Уверен, что '# find' просто использует' String # to_i', поэтому вы можете использовать его, если по какой-то причине вам понадобилась числовая часть. '' 1-john-smith '.to_i => 1' –

+0

Да, действительно. Хотя первоначальная проблема заключалась не в том, как на самом деле разобрать целое число, то в этом случае было бы привязать эту логику к механизму маршрутизации. Похоже, вы можете передавать целые сегменты только как параметры для контроллера. Я не вижу никакого механизма для анализа переменных из регулярного выражения, например. –