我在版本化命名空间中有我的API,
namespace :api do
namespace :v1 do
resources :posts
end
end
但现在当我让我的控制器执行redirect_to @post
时,我收到了Post
的路由错误,因为没有为它定义路由。
def create
@post = Post.new(params[:post])
if @post.save
redirect_to @post
else
# ...
end
end
undefined method `post_url' for #<Api::V1::PostsController:0x007fb9c5fc8858>
我知道我可以更新我的控制器以重定向到指定路线而不是世界末日:
def create
@post = Post.new(params[:post])
if @post.save
redirect_to api_v1_post_url(@post)
# or redirect_to [:api, :v1, @post]
else
# ...
end
end
有没有办法让redirect_to @post
自动检测到它应该是正确的api版本(因此rails可以使用api_v1_post_url
)?我知道我可以覆盖redirect_to
,但实际上我想要一个名称空间感知url_for
,也许rails为此提供了一些钩子?
答案 0 :(得分:7)
Ruby on Rails路由器有三个选项
命名空间(你现在正在使用的东西)
namespace :api do
namespace :v1 do
resources :posts
end
end
控制器:app/controllers/api/v1/PostsController.rb
示例网址路径:example.com/api/v1/posts
范围(仅设置网址路径)
scope 'api/v1' do
resources :posts
end
控制器:app/controllers/PostsController.rb
示例网址路径:example.com/api/v1/posts
模块(仅设置控制器)
scope module: 'api/v1' do
resources :posts
end
控制器:app/controllers/api/v1/PostsController.rb
示例网址路径:example.com/posts
正如您从上面所注意到的,三个人都做了类似于您想要的事情但不是您想要的方式。
我能想到的唯一可以解决使用笨拙的长路径助手api_v1_post_url
的方法是使用命名路由来缩短它。
namespace :api, :as => "a" do
namespace :v1, :as => "1" do
resources :posts
end
end
所以而不是api_v1_post_url
def create
@post = Post.new(params[:post])
if @post.save
redirect_to api_v1_post_url(@post)
end
end
你可以使用更短的a_1_post_url
def create
@post = Post.new(params[:post])
if @post.save
redirect_to a_1_post_url(@post)
end
end
最后,我担心,我不知道如何在rails路由中智能地自动检测命名空间。
希望有所帮助