在Rails 4中确定资源路径

时间:2014-08-02 16:46:25

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

我有resources :shops

会产生/shops/shops/:id

我知道我可以使用

来收集集合或成员
resources :shops do
  scope ":city" do
   # collection and members
  end
end

或之前用

scope ":city" do
 resources :shops
end

但是我无法弄清楚如何让路线成为所有成员(包括标准的REST成员)和集合,就像这样

/shops/:city/

/shops/:city/:id

2 个答案:

答案 0 :(得分:1)

根据您的use case和问题,您尝试使用逻辑上错误的路线。你在城里有商店,而不是商店内的城市。

首先,您应该规范化您的数据库。您应该创建另一个表cities,并将city属性替换为city_id表中的shops

has_manybelongs_to之间需要citiesshops关联。

# Models
class City < ActiveRecord::Base
  has_many :shops
  ... # other stuff
end

class Shop < ActiveRecord::Base
  belongs_to :city
  ... # other stuff
end

路线

resources :cities do
  resources :shops
end

它将生成如下路线:

               POST     /cities/:city_id/shops(.:format)          shops#create
new_city_shop  GET      /cities/:city_id/shops/new(.:format)      shops#new
edit_city_shop GET      /cities/:city_id/shops/:id/edit(.:format) shops#edit
    city_shop  GET      /cities/:city_id/shops/:id(.:format)      shops#show
               PATCH    /cities/:city_id/shops/:id(.:format)      shops#update
               PUT      /cities/:city_id/shops/:id(.:format)      shops#update
               DELETE   /cities/:city_id/shops/:id(.:format)      shops#destroy

从逻辑上讲,这些路线将显示特定商店所在的城市。

答案 1 :(得分:0)

<强>命名空间

您可以考虑加入namespace

由于您正试图为商店提升cities(IE,我想您想在Sao Paulo中展示商店),您可以这样做:

#config/routes.rb
namespace :shops do
   resources :cities, path: "", as: :city, only: [:index] do #-> domain.com/shops/:id/
      resources :shops, path: "", only: [:show] #-> domain.com/shops/:city_id/:id
   end
end

这将允许您创建一个单独的控制器:

#app/controllers/shops/cities_controller.rb
Class Shops::CitiesController < ApplicationController
   def index
      @city = City.find params[:id]
   end
end

#app/controllers/shops/shops_controller.rb
Class Shops::ShopsController < ApplicationController
   def show
      @city = City.find params[:city_id]
      @shop = @city.shops.find params[:id]
   end
end

这将确保您能够创建所需的路由结构。命名空间做了两件重要的事情 -

  
      
  1. 确保您拥有正确的路由结构
  2.   
  3. 分离您的控制器
  4.