Rails深层嵌套与父级索引

时间:2017-07-07 19:19:47

标签: ruby-on-rails ruby-on-rails-4

我有以下路线

  resources :continent do
    resources :countries do
        resource :cities do
            resource :streets
        end
    end
  end

选择我必须做的国家

/continents/:continent_id/countries/:country_id

等等。

我的问题是如何才能获得特定国家或大陆的所有街道。或者特定大陆的所有国家。

例如,有没有办法

/continents/:continent_id/countries/cities

将返回以下所有城市:continent_id

2 个答案:

答案 0 :(得分:3)

  

资源不应该嵌套超过1级深度。请参阅:http://weblog.jamisbuck.org/2007/2/5/nesting-resources

如果你确实需要这种深度,那么你可以用浅属性设置为true来解决这个问题。 请参阅:http://edgeguides.rubyonrails.org/routing.html#shallow-nesting

更新以更好地解释浅嵌套的使用

rails new shallow-routes
cd shallow-routes

修改config/routes.rb以添加所需的路线

  resources :continent do
    resources :countries do
        resource :cities do
            resource :streets
        end
    end
  end

现在正在运行rake routes我们有这个:

                               Prefix Verb   URI Pattern                                                                  Controller#Action
     continent_country_cities_streets POST   /continent/:continent_id/countries/:country_id/cities/streets(.:format)      streets#create
 new_continent_country_cities_streets GET    /continent/:continent_id/countries/:country_id/cities/streets/new(.:format)  streets#new
edit_continent_country_cities_streets GET    /continent/:continent_id/countries/:country_id/cities/streets/edit(.:format) streets#edit
                                      GET    /continent/:continent_id/countries/:country_id/cities/streets(.:format)      streets#show
                                      PATCH  /continent/:continent_id/countries/:country_id/cities/streets(.:format)      streets#update
                                      PUT    /continent/:continent_id/countries/:country_id/cities/streets(.:format)      streets#update
                                      DELETE /continent/:continent_id/countries/:country_id/cities/streets(.:format)      streets#destroy
             continent_country_cities POST   /continent/:continent_id/countries/:country_id/cities(.:format)              cities#create
         new_continent_country_cities GET    /continent/:continent_id/countries/:country_id/cities/new(.:format)          cities#new
        edit_continent_country_cities GET    /continent/:continent_id/countries/:country_id/cities/edit(.:format)         cities#edit
                                      GET    /continent/:continent_id/countries/:country_id/cities(.:format)              cities#show
                                      PATCH  /continent/:continent_id/countries/:country_id/cities(.:format)              cities#update
                                      PUT    /continent/:continent_id/countries/:country_id/cities(.:format)              cities#update
                                      DELETE /continent/:continent_id/countries/:country_id/cities(.:format)              cities#destroy
                  continent_countries GET    /continent/:continent_id/countries(.:format)                                 countries#index
                                      POST   /continent/:continent_id/countries(.:format)                                 countries#create
                new_continent_country GET    /continent/:continent_id/countries/new(.:format)                             countries#new
               edit_continent_country GET    /continent/:continent_id/countries/:id/edit(.:format)                        countries#edit
                    continent_country GET    /continent/:continent_id/countries/:id(.:format)                             countries#show
                                      PATCH  /continent/:continent_id/countries/:id(.:format)                             countries#update
                                      PUT    /continent/:continent_id/countries/:id(.:format)                             countries#update
                                      DELETE /continent/:continent_id/countries/:id(.:format)                             countries#destroy
                      continent_index GET    /continent(.:format)                                                         continent#index
                                      POST   /continent(.:format)                                                         continent#create
                        new_continent GET    /continent/new(.:format)                                                     continent#new
                       edit_continent GET    /continent/:id/edit(.:format)                                                continent#edit
                            continent GET    /continent/:id(.:format)                                                     continent#show
                                      PATCH  /continent/:id(.:format)                                                     continent#update
                                      PUT    /continent/:id(.:format)                                                     continent#update
                                      DELETE /continent/:id(.:format)                                                     continent#destroy

让我们更改用于浅嵌套的资源并查看结果

  resources :continent, shallow: true do
    resources :countries do
        resource :cities do
            resource :streets
        end
    end
  end

结果

                     Prefix Verb   URI Pattern                                          Controller#Action
     country_cities_streets POST   /countries/:country_id/cities/streets(.:format)      streets#create
 new_country_cities_streets GET    /countries/:country_id/cities/streets/new(.:format)  streets#new
edit_country_cities_streets GET    /countries/:country_id/cities/streets/edit(.:format) streets#edit
                            GET    /countries/:country_id/cities/streets(.:format)      streets#show
                            PATCH  /countries/:country_id/cities/streets(.:format)      streets#update
                            PUT    /countries/:country_id/cities/streets(.:format)      streets#update
                            DELETE /countries/:country_id/cities/streets(.:format)      streets#destroy
             country_cities POST   /countries/:country_id/cities(.:format)              cities#create
         new_country_cities GET    /countries/:country_id/cities/new(.:format)          cities#new
        edit_country_cities GET    /countries/:country_id/cities/edit(.:format)         cities#edit
                            GET    /countries/:country_id/cities(.:format)              cities#show
                            PATCH  /countries/:country_id/cities(.:format)              cities#update
                            PUT    /countries/:country_id/cities(.:format)              cities#update
                            DELETE /countries/:country_id/cities(.:format)              cities#destroy
        continent_countries GET    /continent/:continent_id/countries(.:format)         countries#index
                            POST   /continent/:continent_id/countries(.:format)         countries#create
      new_continent_country GET    /continent/:continent_id/countries/new(.:format)     countries#new
               edit_country GET    /countries/:id/edit(.:format)                        countries#edit
                    country GET    /countries/:id(.:format)                             countries#show
                            PATCH  /countries/:id(.:format)                             countries#update
                            PUT    /countries/:id(.:format)                             countries#update
                            DELETE /countries/:id(.:format)                             countries#destroy
            continent_index GET    /continent(.:format)                                 continent#index
                            POST   /continent(.:format)                                 continent#create
              new_continent GET    /continent/new(.:format)                             continent#new
             edit_continent GET    /continent/:id/edit(.:format)                        continent#edit
                  continent GET    /continent/:id(.:format)                             continent#show
                            PATCH  /continent/:id(.:format)                             continent#update
                            PUT    /continent/:id(.:format)                             continent#update
                            DELETE /continent/:id(.:format)                             continent#destroy

为了更好地观看http://i.imgur.com/21CEM7j.png

,它的图像有所不同

我们这里有的是现在路线更简单,像/continent/:continent_id/countries这样的路线现在仅存在于索引,创建和新,其他路线不在大陆范围中路由

请注意,它确实非常有用,因为您不需要路线来告诉您街道位于大陆内部,很明显,如果您的街道位于城市内部,那么它就是当然,在一个国家和大陆之内。

直接回答 - 现在让我们来看看你的目标

  

/大洲/:continent_id /国家/城市

你想要非洲大陆的所有城市,为什么[地狱,对不起]你需要他们之间的国家吗?

我会做/continents/:id/cities,更简单易懂。

要实现这一点,您只需在大陆资源中创建一条新路线

  resources :continent, shallow: true do
    member do
        get 'cities'
    end

    resources :countries do
        resource :cities do
            resource :streets
        end
    end
  end

然后你有了这个新的好路线

cities_continent GET    /continent/:id/cities(.:format)                      continent#cities

答案 1 :(得分:1)

您可以使用以下模型关系

class Country < ActiveRecord::Base
   has_many :streets, :through => : cities
end

因此,您可以在代码中使用

Country.find(1).streets