Автоматически добавлять идентификатор родительской модели во вложенные ресурсы - PullRequest
3 голосов
/ 28 марта 2011

С вложенными маршрутами ресурсов в Rails 3, такими как:

resources :magazines do
  resources :ads
end
Определены

помощники, такие как magazine_ad_path, на которые я должен передать и журнал, и объявление, что неудобно, если у меня есть только ссылка на объявление:

magazine_ad_path(@ad.magazine, @ad)

Есть ли хороший способ настроить помощника ad_path, который берет @ad и возвращает соответствующий адрес, включая идентификатор журнала? (Это также позволило бы использовать link_to @ad, redirect_to @ad и т. Д., Которые автоматически вызывают хелпер ad_path, соответствующий классу модели.)

Ответы [ 3 ]

2 голосов
/ 28 марта 2011

Неглубокая маршрутизация - это то, что вы ищете. Вы можете реализовать мелкое вложение, как показано ниже:

resources :magazines do
  shallow do
    resources :ads
  end
end

OR

resources :magazines, :shallow => true do
  resources :ads
end

Вложены только индекс и новые действия.

Использование вложенных ресурсов приводит к генерации длинных URL-адресов, а поверхностное вложение помогает удалить части (которые также содержат маршрут родительского ресурса), которые не обязательно требуются для определенных действий (поскольку родительский ресурс может быть получен из постоянной дочерней записи) .

0 голосов
/ 02 апреля 2011

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

class Ad
  def path action=nil
    [action, magazine, self]
  end
end

Тогда, по вашему мнению, вы можете использовать этот массив в качестве полиморфного маршрута:

link_to @ad.path
link_to @ad.path(:edit)

Конечно, это также работает с redirect_to и т. Д.

0 голосов
/ 30 марта 2011

Одно из возможных, но уродливых решений:

module RoutesHelper
  def ad_path(ad)
    magazine_ad_path(ad.magazine, ad)
  end

  def ad_url(ad)
    magazine_ad_url(ad.magazine, ad)
  end

  def edit_ad_path(ad)
    edit_magazine_ad_path(ad.magazine, ad)
  end

  def edit_ad_url(ad)
    edit_magazine_ad_url(ad.magazine, ad)
  end

  ...
end

[ActionView::Base, ActionController::Base].each do |m|
  m.module_eval { include RoutesHelper }
end

К сожалению, у этого недостатка есть то, что мне приходится определять различные помощники для _path и _url, поскольку redirect_to использует помощники _urlЯ должен написать edit_ помощников вручную (и, может быть, мне не хватает некоторых; я не уверен в этом), и это просто безобразно.

...