一个 'Posts' 资源有两条不同的路线?
One 'Posts' resource with two different routes?
我想使用一个 'posts' 控制器获取两条(或更多条)不同路线的所有 restful 路线。我在一个多品牌网站上工作,我正在努力减少重复代码。
brand1/blog/:id
brand2/blog/:id
现在我有:
resources :posts, :path => "brand1/blog"
get 'brand2/blog' => 'posts#brand2_index'
我可以使用 @post.brand 参数让这两个博客正确显示,但个别 post url 最终总是针对 brand1。
我对 rails 和一般编程还很陌生,所以我肯定会遗漏一些基本知识。
非常感谢任何帮助。谢谢!
尝试如下嵌套您的资源,然后 运行 rake routes
看看您得到了什么。
resources :posts do
get 'brand1/blog', to: "posts#brand1_index"
get 'brand2/blog', to: "posts#brand2_index"
end
贾斯汀
处理此问题的一种简洁方法是使用范围。您可以这样定义路线:
scope ':brand_name' do
resources :posts, path: 'blog'
end
无需重复控制器操作。在您的控制器中,您将获得带有 params[:brand_name]
的品牌。生成的路由如下:
posts GET /:brand_name/blog(.:format) posts#index
POST /:brand_name/blog(.:format) posts#create
new_post GET /:brand_name/blog/new(.:format) posts#new
edit_post GET /:brand_name/blog/:id/edit(.:format) posts#edit
post GET /:brand_name/blog/:id(.:format) posts#show
PATCH /:brand_name/blog/:id(.:format) posts#update
PUT /:brand_name/blog/:id(.:format) posts#update
DELETE /:brand_name/blog/:id(.:format) posts#destroy
page GET /pages/*id high_voltage/pages#show
这通常包含在 nested resources:
#config/routes.rb
resources :brands, path: "", only: [] do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand_id/blog/:id
end
由于您没有使用 brands
作为资源,因此您需要使用 scope
(不需要控制器):
#config/routes.rb
scope :brand do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand/blog/:id
end
然后您将能够在您的参数中选择 :brand
:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def show
@brand = Brand.find params[:brand]
@post = @brand.posts.find params[:id]
end
end
--
如果您想确保只有有效的品牌被接受为路线,您需要使用自定义约束:
#config/routes.rb
scope :brand, constraints: BrandExists do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand/blog/:id
end
#lib/brand_exists.rb
module BrandExists
def initializer(router)
@router = router
end
def self.matches?(request)
Brand.exists? request.path.split("/").first
end
end
我想使用一个 'posts' 控制器获取两条(或更多条)不同路线的所有 restful 路线。我在一个多品牌网站上工作,我正在努力减少重复代码。
brand1/blog/:id
brand2/blog/:id
现在我有:
resources :posts, :path => "brand1/blog"
get 'brand2/blog' => 'posts#brand2_index'
我可以使用 @post.brand 参数让这两个博客正确显示,但个别 post url 最终总是针对 brand1。
我对 rails 和一般编程还很陌生,所以我肯定会遗漏一些基本知识。
非常感谢任何帮助。谢谢!
尝试如下嵌套您的资源,然后 运行 rake routes
看看您得到了什么。
resources :posts do
get 'brand1/blog', to: "posts#brand1_index"
get 'brand2/blog', to: "posts#brand2_index"
end
贾斯汀
处理此问题的一种简洁方法是使用范围。您可以这样定义路线:
scope ':brand_name' do
resources :posts, path: 'blog'
end
无需重复控制器操作。在您的控制器中,您将获得带有 params[:brand_name]
的品牌。生成的路由如下:
posts GET /:brand_name/blog(.:format) posts#index
POST /:brand_name/blog(.:format) posts#create
new_post GET /:brand_name/blog/new(.:format) posts#new
edit_post GET /:brand_name/blog/:id/edit(.:format) posts#edit
post GET /:brand_name/blog/:id(.:format) posts#show
PATCH /:brand_name/blog/:id(.:format) posts#update
PUT /:brand_name/blog/:id(.:format) posts#update
DELETE /:brand_name/blog/:id(.:format) posts#destroy
page GET /pages/*id high_voltage/pages#show
这通常包含在 nested resources:
#config/routes.rb
resources :brands, path: "", only: [] do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand_id/blog/:id
end
由于您没有使用 brands
作为资源,因此您需要使用 scope
(不需要控制器):
#config/routes.rb
scope :brand do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand/blog/:id
end
然后您将能够在您的参数中选择 :brand
:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def show
@brand = Brand.find params[:brand]
@post = @brand.posts.find params[:id]
end
end
--
如果您想确保只有有效的品牌被接受为路线,您需要使用自定义约束:
#config/routes.rb
scope :brand, constraints: BrandExists do
resources :posts, path: "blog", only: [:index, :show] #-> url.com/:brand/blog/:id
end
#lib/brand_exists.rb
module BrandExists
def initializer(router)
@router = router
end
def self.matches?(request)
Brand.exists? request.path.split("/").first
end
end