Rails 3 вложенных ресурса короткое имя? - PullRequest
7 голосов
/ 02 октября 2011

Я нахожусь в процессе обновления приложения Rails 2.3 до Rails 3. В маршрутизаторе Rails 2.3 было возможно установить :name_prefix nil для вложенных ресурсов, чтобы получить более короткое имя.Фактический URL-адрес будет по-прежнему полностью определен, но код может использовать более короткое имя.Например,

 map.resources :sites do |site|
    site.resources :groups, :as => :groups, :controller => :url_groups, :name_prefix => nil, :member => { :clone => :post } do |group|
      group.resources :tests, :as => :tests, :controller => :test_runs, :name_prefix => nil, :collection => { :latest => :get }
    end
  end

позволит использовать latest_tests_path.Я не могу понять, как сделать то же самое с Rails 3, поэтому я застрял с latest_site_group_tests_path.Если это так, то я могу просто просмотреть код и изменить каждый его экземпляр.Но я хотел убедиться, что я ничего не пропустил первым.И что бы там ни было, мне нужно поддерживать структуру URL-адреса, поэтому мелкие маршруты, похоже, не являются ответом.

Ответы [ 3 ]

8 голосов
/ 04 октября 2011

Хорошая новость заключается в том, что в Rails 3 все еще есть возможность настраивать произвольные / сокращенные помощники по URL.Вместо параметра для метода resources вы можете создавать сокращенные помощники url с объявлением match в routs.rb.

Скажем, у нас настроены маршруты следующим образом (отмечая, что вам необходимо поддерживать 3 уровня вложенности):

resources :sites do
  resources :groups, :controller => :url_groups do
    member do
      post :clone
    end
    resources :test_runs do
      collection do
        get :latest
      end
    end
  end
end

Мы получаем все стандартные помощники по URL (rake routes):

           clone_site_group POST   /sites/:site_id/groups/:id/clone(.:format)                    {:action=>"clone", :controller=>"url_groups"}
latest_site_group_test_runs GET    /sites/:site_id/groups/:group_id/test_runs/latest(.:format)   {:action=>"latest", :controller=>"test_runs"}
       site_group_test_runs GET    /sites/:site_id/groups/:group_id/test_runs(.:format)          {:action=>"index", :controller=>"test_runs"}
                           (etc)

Но чтобы создать что-то более короткое, чем latest_site_group_test_runs_path(site,group), добавьте объявление о совпадении в route.rb следующим образом:

match 'sites/:site_id/groups/:id/test_runs/latest' => 'test_runs#latest', :as => :latest_tests

Теперь вы можете использовать latest_tests_path (site, group) или latest_tests_url(сайт, группа) для генерации полностью вложенного пути.

Если ваша цель - краткость, вы также можете использовать неявные полиморфные пути (при условии, что все ваши модели выровнены с путями ресурсов).

Например, учитывая @site # 1 и @group # 1, все последующее теперь сгенерирует один и тот же путь '/sites/1/groups/1/test_runs/latest':

= link_to "latest tests", latest_site_group_test_runs_path(@site,@group) # std helper
= link_to "latest tests", latest_tests_path(@site,@group) # match helper
= link_to "latest tests", [:latest,@site,@group,:test_runs] # implicit polymorphic path

Надеюсь, это поможет!Похоже, вы должны быть в состоянии получить гибкость, необходимую для переноса приложения.

Примечание: я закрыл глаза на скрытую проблему наличия модели под названием «Тест», поскольку это не по теме ;-)Вот несколько названий моделей, которые являются источником постоянной боли из-за конфликтов пространства имен и ключевых слов.Мой другой фаворит - это когда я действительно хотел иметь режим под названием «Case» (поскольку он лучше всего соответствовал проблемной области. Плохая идея, быстро меняющаяся!)

2 голосов
/ 21 марта 2013

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

resources :sites

scope :path => '/sites/:site_id' do
  resources :groups, :controller => :url_groups do
    post :clone, :on => :member
  end
end

scope :path => '/sites/:site_id/groups/:group_id' do
  resources :tests, :controller => :test_runs do
    get :latest, :on => :collection
  end
end

Выход rake routes:

       sites GET        /sites(.:format)                                             sites#index
             POST       /sites(.:format)                                             sites#create
    new_site GET        /sites/new(.:format)                                         sites#new
   edit_site GET        /sites/:id/edit(.:format)                                    sites#edit
        site GET        /sites/:id(.:format)                                         sites#show
             PUT        /sites/:id(.:format)                                         sites#update
             DELETE     /sites/:id(.:format)                                         sites#destroy
 clone_group POST       /sites/:site_id/groups/:id/clone(.:format)                   url_groups#clone
      groups GET        /sites/:site_id/groups(.:format)                             url_groups#index
             POST       /sites/:site_id/groups(.:format)                             url_groups#create
   new_group GET        /sites/:site_id/groups/new(.:format)                         url_groups#new
  edit_group GET        /sites/:site_id/groups/:id/edit(.:format)                    url_groups#edit
       group GET        /sites/:site_id/groups/:id(.:format)                         url_groups#show
             PUT        /sites/:site_id/groups/:id(.:format)                         url_groups#update
             DELETE     /sites/:site_id/groups/:id(.:format)                         url_groups#destroy
latest_tests GET        /sites/:site_id/groups/:group_id/tests/latest(.:format)      test_runs#latest
       tests GET        /sites/:site_id/groups/:group_id/tests(.:format)             test_runs#index
             POST       /sites/:site_id/groups/:group_id/tests(.:format)             test_runs#create
    new_test GET        /sites/:site_id/groups/:group_id/tests/new(.:format)         test_runs#new
   edit_test GET        /sites/:site_id/groups/:group_id/tests/:id/edit(.:format)    test_runs#edit
        test GET        /sites/:site_id/groups/:group_id/tests/:id(.:format)         test_runs#show
             PUT        /sites/:site_id/groups/:group_id/tests/:id(.:format)         test_runs#update
             DELETE     /sites/:site_id/groups/:group_id/tests/:id(.:format)         test_runs#destroy

Обновление: Ду, я исключил статические сегменты путей области из моего примера.Исправлено.

2 голосов
/ 02 октября 2011

Есть опция :shallow (см. Документацию ), но я не уверен, что она подходит для вашего случая использования:

resources :sites, :shallow => true
  resources :groups do
    resources :tests
  end
end

Недостатком является создание группыдополнительных маршрутов:

   group_tests GET    /groups/:group_id/tests(.:format)        {:action=>"index", :controller=>"tests"}
               POST   /groups/:group_id/tests(.:format)        {:action=>"create", :controller=>"tests"}
new_group_test GET    /groups/:group_id/tests/creer(.:format)  {:action=>"new", :controller=>"tests"}
     edit_test GET    /tests/:id/modifier(.:format)            {:action=>"edit", :controller=>"tests"}
          test GET    /tests/:id(.:format)                     {:action=>"show", :controller=>"tests"}
               PUT    /tests/:id(.:format)                     {:action=>"update", :controller=>"tests"}
               DELETE /tests/:id(.:format)                     {:action=>"destroy", :controller=>"tests"}
   site_groups GET    /sites/:site_id/groups(.:format)         {:action=>"index", :controller=>"groups"}
               POST   /sites/:site_id/groups(.:format)         {:action=>"create", :controller=>"groups"}
new_site_group GET    /sites/:site_id/groups/creer(.:format)   {:action=>"new", :controller=>"groups"}
    edit_group GET    /groups/:id/modifier(.:format)           {:action=>"edit", :controller=>"groups"}
         group GET    /groups/:id(.:format)                    {:action=>"show", :controller=>"groups"}
               PUT    /groups/:id(.:format)                    {:action=>"update", :controller=>"groups"}
               DELETE /groups/:id(.:format)                    {:action=>"destroy", :controller=>"groups"}
         sites GET    /sites(.:format)                         {:action=>"index", :controller=>"sites"}
               POST   /sites(.:format)                         {:action=>"create", :controller=>"sites"}
      new_site GET    /sites/creer(.:format)                   {:action=>"new", :controller=>"sites"}
     edit_site GET    /sites/:id/modifier(.:format)            {:action=>"edit", :controller=>"sites"}
          site GET    /sites/:id(.:format)                     {:action=>"show", :controller=>"sites"}
               PUT    /sites/:id(.:format)                     {:action=>"update", :controller=>"sites"}
               DELETE /sites/:id(.:format)                     {:action=>"destroy", :controller=>"sites"}

Кроме того, поверхностное вложение относится только к следующим маршрутам: :show, :edit, :update, :destroy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...