如果我有这些模型:
Product, belongs_to :category, belongs_to :shop
Category, has_many :products
Shop, has_many :products
我想要这些端点:
/products/:category_id #all products for a category
/products/:shop_id #all products for a shop
这可能吗,在路由中可能有条件?还是应该使用不同的端点?
使用单个端点不是一个好主意,因为如果id段是类别或商店id甚至是产品id,那么它将是模糊的。它也与REST中的整个思想相冲突,即/things/:id
应该为您提供该集合的成员。
在Rails约定(以及一般的REST)中,您只需创建多个嵌套资源:
/categories/:category_id/products
/shops/:shop_id/products
您可以通过简单地嵌套对资源宏的调用来做到这一点:
resources :categories do
resources :products, only: [:new, :create, :index]
end
resources :shops do
resources :products, only: [:new, :create, :index]
end
这将生成命名的路由助手category_products_path
和shop_products_path
。
请记住,任何给定的模型都可以有不同的端点来描述它与其他模型的关系,任何执行多个特定任务的端点都应该被视为代码气味。
我是这样解决的:
路线:
class CategoryConstraint
def self.matches?(request)
Category.where(id: request.path_parameters[:id]).any?
end
end
post 'products/:id', to: 'products#category_products', constraints: CategoryConstraint
post 'products/:id', to: 'products#shop_products'
如果有人有更好的解决办法,我会接受的。