Проверять отсутствие перекрытия маршрутизации при создании новых ресурсов в Ruby on Rails - PullRequest
0 голосов
/ 14 июля 2009

У меня есть RESTful-настройка для маршрутов в приложении Rails с использованием текстовых постоянных ссылок в качестве идентификатора ресурсов.

Кроме того, есть несколько специальных именованных маршрутов, которые пересекаются с именованным ресурсом, например ::100100

# bunch of special URLs for one off views to be exposed, not RESTful
map.connect '/products/specials', :controller => 'products', :action => 'specials'
map.connect '/products/new-in-stock', :controller => 'products', :action => 'new_in_stock'

# the real resource where the products are exposed at
map.resources :products

Модель Product использует permalink_fu для генерации постоянных ссылок на основе имени, а ProductsController выполняет поиск в поле постоянных ссылок при доступе. Это все отлично работает.

Однако при создании новых Product записей в базе данных я хочу проверить, что сгенерированная постоянная ссылка не пересекается со специальным URL.

Если пользователь пытается создать продукт с именем specials или new-in-stock или даже обычный метод ресурсов RESTful Rails, такой как new или edit, я хочу, чтобы контроллер просматривал конфигурацию маршрутизации, устанавливал ошибки на объект модели, не пройдена валидация для новой записи и не сохранена.

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

(имена контроллеров и моделей изменены, чтобы защитить невинных и упростить ответ; фактическая настройка сложнее, чем в этом примере)

Ответы [ 3 ]

1 голос
/ 14 июля 2009

Ну, это работает, но я не уверен, насколько это красиво. Основная проблема заключается в смешении контроллера / логики маршрутизации в модели. По сути, вы можете добавить пользовательскую проверку модели, чтобы проверить ее. Это использует недокументированные методы маршрутизации, поэтому я не уверен, насколько стабильно это будет идти вперед У кого-нибудь есть идеи получше?

class Product < ActiveRecord::Base
  #... other logic and stuff here...

  validate :generated_permalink_is_not_reserved

  def generated_permalink_is_not_reserved
    create_unique_permalink # permalink_fu method to set up permalink
    #TODO feels really ugly having controller/routing logic in the model. Maybe extract this out and inject it somehow so the model doesn't depend on routing
    unless ActionController::Routing::Routes.recognize_path("/products/#{permalink}", :method => :get) == {:controller => 'products', :id => permalink, :action => 'show'}
      errors.add(:name, "is reserved")
    end
  end
end
0 голосов
/ 22 июля 2009

Лучше практиковать явное управление URI самостоятельно по таким причинам, чтобы избежать случайного раскрытия маршрутов, которые вам не нужны.

0 голосов
/ 14 июля 2009

Вы можете использовать маршрут, который иначе не существовал бы. Таким образом, не имеет никакого значения, если кто-то выберет зарезервированное слово для названия или нет.

map.product_view '/product_view/:permalink', :controller => 'products', :action => 'view'

А по вашему мнению:

product_view_path(:permalink => @product.permalink)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...