Rails 3 nested resources short name?

后端 未结 3 2046
攒了一身酷
攒了一身酷 2021-02-15 23:19

I\'m in the process of upgrading a Rails 2.3 app to Rails 3. In the Rails 2.3 router, it was possible to set a :name_prefix of nil on nested resources to get a sho

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-16 00:18

    Good news is that Rails 3 still has the ability to setup arbitrary/abbreviated url helpers. Rather than a parameter to the resources method, you can create short-hand url helpers with the match declaration in routes.rb.

    Say we have routes setup like this (noting that you need to maintain the 3 levels of nesting):

    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
    

    We get all the standard url helpers (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)
    

    But to create something shorter than latest_site_group_test_runs_path(site,group), add a match declaration to routes.rb like this:

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

    Now you can use latest_tests_path(site,group) or latest_tests_url(site,group) to generate the fully nested path.

    If your aim is brevity, you could also use implicit polymorphic paths (as long as you have all your models aligned with resource paths).

    For example, given @site #1 and @group #1, all of the following will now generate the same path '/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
    

    Hope that helps! Seems like you should be able to get the flexibility you need for the app migration.

    NB: I glossed over the lurking issue of having a model called "Test" since that's off topic;-) There are a few model names that are a neverending source of pain because of namespace and keyword conflicts. My other favourite is when I really wanted to have a mode called "Case" (since that matched the problem domain best. Bad idea, rapidly reversed!)

提交回复
热议问题