I am using the Rails-Api (4) and I want only three routes for my namespaced routes file.
In my routes.rb file, I am trying to do this:
namespace :api do
namespace :v1 do
resources :documents, only: [:get, :create]
resource :system_status, only: [:get]
end
end
rake routes gets me only this:
Prefix Verb URI Pattern Controller#Action
api_v1_documents POST /api/v1/documents(.:format) api/v1/documents#create
If a take the the only: off, it works and gives me all the routes (which I don't want).
I also tried this:
namespace :api do
namespace :v1 do
post '/documents', to: 'documents#create'
get '/documents/:id', to: 'documents#show'
get '/system_status', to: 'system_status#show'
end
end
Gets me this odd output in rake routes:
Prefix Verb URI Pattern Controller#Action
api_v1_documents POST /api/v1/documents(.:format) api/v1/documents#create
api_v1 GET /api/v1/documents/:id(.:format) api/v1/documents#show
api_v1_system_status GET /api/v1/system_status(.:format) api/v1/system_status#show
Not sure what's up with documents#show getting me only api_v1 as it's prefix.
Looks like you're getting mixed up between HTTP verbs and their corresponding Rails actions. There is no resource route for :get, but there are two routes for a GET request, which are :index, and :show
Change your original resource-based routing to this instead:
namespace :api do
namespace :v1 do
resources :documents, only: [:show, :create]
resource :system_status, only: [:show]
end
end
And that should give you the proper routes, plus the correct URL helper prefixes.
Related
I'm attempting to maintain some legacy code but I'm struggling to figure out why my defined route isn't working.
The error I'm getting is
Started POST "/api/transactions/weight" ...
ActionController::RoutingError (No route matches [POST] "/api/transactions/weight"):
My (simplified) route is as follows
namespace :api do
resources :transactions, only: [:create] do
post "weight", to: "transactions#weight"
end
end
I've also tried moving the route outside the resource :transactions definition like so
namespace :api do
resources :transactions, only: [:create]
post "transactions/weight", to: "transactions#weight"
end
But I'm getting the same error. Am I misunderstanding route definition, or is the problem elsewhere? Thanks
Always check bundle exec rake routes to understand your routes.
The post method defines "/weight" route as a member route (acting on a specific "transactions" resource
# bundle exec rake routes
api_transaction_weight POST /api/transactions/:transaction_id/weight(.:format). api/transactions#weight
By default, if you don't specify on: option, the route inside resources block gets created as member route.
You want to specify it as a collection route [1] via on: :collection
namespace :api do
resources :transactions, only: [:create] do
post "weight", to: "transactions#weight", on: :collection
end
end
# bundle exec rake routes
weight_api_transactions POST /api/transactions/weight(.:format) api/transactions#weight
[1] https://guides.rubyonrails.org/routing.html#adding-collection-routes
The way you defined routes will consider "weight" as the member route. If you want to define it as collection route.
namespace :api do
resources :transactions, only: [:create] do
collection {post :weight}
end
end
The above convention will expose weight as collection route and not member route.If you want to be defined as member post request. Then use following convention
namespace :api do
resources :transactions, only: [:create] do
member {post :weight}
end
end
If you are using api.rb as draw file in routes, then you need to restart your application to reflect changes in routes file.
Rails.application.routes.draw do
resources :users, only: [:index]
end
This is how I have my routes set up in my project. However it is not getting the route and I get an error:
No route matches [GET] "/index"
However my code below gives me no issues
Rails.application.routes.draw do
get "/index", to: "users#index"
#resources :users, only: [:index]
end
I am not sure what I am doing wrong. My controller and view files are set up properly, it just won't let me use resources for my routes. Any suggestions?
This particular code is
Rails.application.routes.draw do
resources :users, only: [:index]
end
generating a route for you with rails convention. By convention I mean that you have to send a GET request to /users in order to work. If you want to get users with /index you should use the second chunk of code you provided.
Basically
Rails.application.routes.draw do
get "/index", to: "users#index"
end
is rerouting your index request to user index, and just telling rails to where to find it.
In my routes file I have the following:
Rails.application.routes.draw do
namespace :foobarbazz do
resource :blog, only: [:index]
end
end
Currently the blog resource will only be directed to the #index action on GET requests. Is there a way to make this namespaced controller action also respond to POST requests?
Create a custom router:
namespace :foobarbazz do
resource :blog, only: [:index]
post "/blogs", to: "blogs#index"
end
Also:
namespace :foobarbazz do
match 'blog', to: 'blog#index', via: [:get, :post]
end
See http://guides.rubyonrails.org/routing.html#http-verb-constraints
Here is my route:
resources :campaigns, only: [:index, :show]
get '/signs/:sign_id', to: 'signs#show', as: 'sign'
#...others like this...
I'm wanting to append a sub-route to the end of each of the routes above. The sub-route I want to append is:
'/location/:location_id'
This way, I would be able to access:
/campaigns/1
/campaigns/1/location/2
/signs/13
/signs/1/location/12
etc.
I looked into Routing Concerns, but I'm not sure if that would solve my problem. I tried something like this:
#routes.rb
concern :locationable do
member do
get '/location/:location_id'
end
end
resources :campaigns, only: [:show], concerns: :locationable
But obviously this is wrong and it does not work (does not add anything to rake routes). How can I achieve a dry routing solution?
Define the location route as a resource under the concern, like this:
concern :locationable do
resources :locations, only: :show
end
resources :campaigns, only: :show, concerns: :locationable
resources :signs, only: :show, concerns: :locationable
That will generate the following routes:
$ rake routes
Prefix Verb URI Pattern Controller#Action
campaign_location GET /campaigns/:campaign_id/locations/:id(.:format) locations#show
campaign GET /campaigns/:id(.:format) campaigns#show
sign_location GET /signs/:sign_id/locations/:id(.:format) locations#show
sign GET /signs/:id(.:format) signs#show
Source: http://guides.rubyonrails.org/routing.html#routing-concerns
I'm trying to set up routes for a mobile API, which should have a versioned api-path. I already could make the mobile Auth work, which is implemented in a separate Controller AuthController located in /controllers/api/v1/mobile/.
Usage example:
myapp.com/api/v1/mobile/auth
But now I want to register my existing ressources-Controllers to this path-pattern as additional api-routes. Concrete: this would be the TasksController located at /controllers/tracker/tasks_controller.rb. So I added a mobile route to the routes-definition:
# routes.rb
namespace :tracker, path: 'timetracking' do
resources :tasks, 'jobs'
end
namespace :api do
namespace :v1 do
namespace :mobile do
resources :auth, :only => [:create, :destroy]
namespace :tracker do #added mobile route
resource :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
end
end
end
But when I call myapp.com/api/v1/mobile/tracker/tasks it results in an error-message:
Routing Error
uninitialized constant Api::V1::Mobile::Tracker
I especially added the alias :mobile_tasks to this route, to avoid any conflicts with the original tasks-route above. Any ideas, how to set the controller properly for this route?
Update#1
Defining this route as a scope instead of a namespace, didn't work aswell.
scope "/api/v1/mobile/tracker" do
resources :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
But this time, it didn't even resolve the route-path itself.
Routing Error
No route matches [GET] "/api/v1/mobile/tracker/tasks"
I assume it might be a problem, that my additional mobile-api route tries to point to a completely different namespace tracker.
According to http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing you should use scope instead of namespace.
If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use:
scope "/admin" do
resources :posts, :comments
end
Adding this answer to get clarity on namespace & scope.
When you use namespace, it will prefix the URL path for the specified resources, and try to locate the controller under a module named in the same manner as the namespace.
# config/routes.rb
namespace :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
When we add scope, it will just map the controller action for the given scope patterns. No need to define controller under any module.
# config/routes.rb
scope :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) posts#index
Note that, controller is just posts controller without any module namespace.
If we add a path option to scope it will map to the controller with the path option specified as follows
# config/routes.rb
scope module: 'admin', path: 'admin' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
Note that the controller now is under admin module.
Now, if we want to change the name of path method to identify resource, we can add as option to scope.
# config/routes.rb
namespace module: 'admin', path: 'admin', as: 'root' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
root_posts GET /admin/posts(.:format) admin/posts#index
You can see the change in the Prefix Verb.
Hope it helps others.
Late answer, but still might be helpful:
scope '/v1' do
resources :articles, module: 'v1'
end
controller
# app/controller/v1/articles_controller.rb
class V1::ArticlesController < ApplicationController
end
Now you should be able to access this url:
http://localhost:3000/v1/articles