Я даже не знаю, как написать правильное название для этого. Я как бы собрал воедино некоторый код маршрутизации, основанный на куче разных статей, и теперь мне интересно, нарисовал ли я себя в углу.
У меня есть модель NewsArticle, и я хочу, чтобы ссылки выглядели так:
/news # List of all articles
/news/2011 # List of articles published this year
/news/2011/06 # List of articles published this month
/news/2011/06/28 # List of articles published on this day
/news/2011/06/28/my-post-title # Actual article
Хорошо, уже идем против Rails, но пусть будет так.
У меня есть маршруты, настроенные так:
controller :news_articles, :via => [:get] do
match '/news(/:year/(/:month(/:day)))' => :index, :constraints => { :year => /\d{4}/, :month => /\d{2}/, :day => /\d{2}/ }
match '/news/:year/:month/:day/:id' => :show
end
Обратите внимание, что :as
декларация отсутствует. Это потому, что когда я добавляю что-то вроде :as => "news_archive"
, я получаю news_archive_path
, который возвращает что-то глупое, например "/ news? Year = 2010 & month = 4". Итак, я исключил этот бит и записал свои собственные методы пути в файл помощника приложения:
def news_archive_path(year = nil, month = nil, day = nil)
return "/news" if year.nil?
t = Time.zone.local(year.to_i, month.nil? ? nil : month.to_i, day.nil? ? nil : day.to_i)
if month.nil?
"/news/#{t.year}"
elsif day.nil?
"/news/#{t.year}/#{"%02d" % t.month}"
else
"/news/#{t.year}/#{"%02d" % t.month}/#{"%02d" % t.day}"
end
end
def news_article_path(article)
t = article.published_at.in_time_zone
"#{news_archive_path(t.year, t.month, t.day)}/#{article.friendly_id}"
end
Отлично, все это работает на практике. Но теперь я столкнулся с проблемой, когда я тестирую свои контроллеры и хочу убедиться, что на визуализированных шаблонах отображаются правильные ссылки. (О да, я не держу отдельные тесты представления, но вместо этого использую render_views
в моих тестах контроллера.) Но тесты не выполняются с ошибкой undefined method
news_article_path 'для # `.
Так, я только что подошел ко всему неправильно и нарисовал себя в углу? Или можно из этого как-то включить вспомогательные методы в тест контроллера? Или я просто смирюсь с этим, чтобы пройти тест и жестко закодировать ссылки, как я ожидаю?