I have my API in a versioned namespace,
namespace :api do
namespace :v1 do
resources :posts
end
end
but now when I have my controller do a redirect_to @post
I get a route error for Post
because no routes are defined for it.
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>
I know I can update my controller to redirect to the named route and its not the end of the world:
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
Is there a way to make redirect_to @post
automatically detect that it should be in the right api version (so rails works out to use api_v1_post_url
)? I know I could overwrite redirect_to
but really I want a namespace aware url_for
, maybe rails provides some hooks for this?
Any object that you want users to be able to access via URI and perform CRUD (or some subset thereof) operations on can be thought of as a resource. In the Rails sense, it is generally a database table which is represented by a model, and acted on through a controller.
Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. A single call to resources can declare all of the necessary routes for your index , show , new , edit , create , update , and destroy actions.
The routing module provides URL rewriting in native Ruby. It's a way to redirect incoming requests to controllers and actions. It replaces the mod_rewrite rules.
There are three options in Ruby on Rails router
1. Namespaces(something which are you using right now)
namespace :api do
namespace :v1 do
resources :posts
end
end
Controller: app/controllers/api/v1/PostsController.rb
Example URL Path: example.com/api/v1/posts
2. Scope(only sets the url path)
scope 'api/v1' do
resources :posts
end
Controller: app/controllers/PostsController.rb
Example URL Path: example.com/api/v1/posts
3. Module(only sets the controller)
scope module: 'api/v1' do
resources :posts
end
Controller: app/controllers/api/v1/PostsController.rb
Example URL Path: example.com/posts
As you may notice from above, all of three do something similar to what you want but not the way you want it.
the only workaround I can think of against using awkwardly long path helpers api_v1_post_url
is to use named routes to shorten it.
namespace :api, :as => "a" do
namespace :v1, :as => "1" do
resources :posts
end
end
so instead of api_v1_post_url
def create
@post = Post.new(params[:post])
if @post.save
redirect_to api_v1_post_url(@post)
end
end
you can use little shorter a_1_post_url
def create
@post = Post.new(params[:post])
if @post.save
redirect_to a_1_post_url(@post)
end
end
Lastly, I am afraid, I am not aware of any way to intelligently auto-detect namespacing in rails routing.
Hope it helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With