Rails namespace routes and custom action on resource - ruby-on-rails

I currently have these routes set up:
namespace :api do
namespace :v1 do
resources :users do
match 'api/v1/users/all'
end
resources :sessions
end
end
I'm trying to set up a custom actio nin my users controller called "all".
How do I get the route for that to match? I've tried these, and get no route errors:
resources :users do
match 'api/v1/users/all' => "users#all" (also "api/v1/users#all" and "api_v1_users#all"
end
What is the route that will enable me to connect with my custom action?
Thanks

You need to add a collection
namespace :api do
namespace :v1 do
resources :users do
collection do
get 'all'
end
end
resources :sessions
end
end
The namespace and resources method calls create the hierarchy; a route nested with the resource :users block will take on the path of it's ancestors. The collection creates nested routes on the resource collection instead of single instances of the resource.
/api/v1/users/all
Recommended Reading: http://guides.rubyonrails.org/routing.html#adding-collection-routes

Related

How can i create an route for search article?

i want to create a route to search an article
should be able to add the size or the page
like this
'/post/1/article/search?size=200&page=1
it will be good like this?
get '/post/:id/article/search/:size/:page
can i create that endpoint directly with rails?
namespace :api do
namespace :v1 do
resources :posts do
resources :articles
get /search/:size/:page
Something like this should work:
namespace :api do
namespace :v1 do
resources :posts do
resources :articles do
collection do
get "/search/:size/:page", action: :search, defaults: { size: 200, page: 1 }
end
end
end
end
end
In your controller, you'll be able to access via: params[:size] and params[:page].
NOTES 👀
If you just need to send as regular parameters ?size=200&page=1, you don't need to define the parameters in the route itself. The "querystring" was always sent to Rails controllers:
collection do
get :search
end
The defaults are not mandatory, but in such case I think it's a good idea as you will always have a fallback value for those parameters.
You can read further details in the official guides:
"collection" routes: https://guides.rubyonrails.org/routing.html#adding-collection-routes
"non-resourceful" routes: https://guides.rubyonrails.org/routing.html#non-resourceful-routes

Ruby on Rails No route matches [POST]

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.

Prevent a route from matching on the wrong namespace?

I have an API with an admin namespace that has many of the same routes as the parent namespace:
App::Application.routes.draw do
namespace :api do
resources :posts
namespace :admin do
resources :posts
end
end
end
Whenever I try to navigate to /api/admin/posts, I hit the controller action for /api/posts.
Is it possible to prevent matching the first route when I am in fact trying to hit the admin namespace?

How do I get the name of the route namespace within its block?

I am calling a custom method within a namespaced route.
# config/routes.rb
namespace :v1 do
some_custom_method :users
end
Within some_custom_method I would like to access the namespace (v1). How?

Customizing named route in Rails 3

I would like to create a resourceful route on a resource member, but I can't seem to find the syntax to create the named route that I want.
namespace :admin
resources :foobars do
get :attribute, on: :member, as: :attribute
end
end
This will provide a route method called:
attribute_admin_foobar_path
I would like it to say:
admin_foobar_attribute_path
The only other way I can think of would be to reject the resources block and create a single route:
namespace :admin
resources :foobars
get 'foobars/:id/attribute', as: :foobar_attribute
end
However, I don't like this approach because it forces me to duplicate the routing structure of already existing routes...not very DRY.
Is there a way that I can create the route name that I want while still using the resources routing block?
If you do it like this:
namespace :admin do
resources :foobars do
get :attribute
end
end
You will get:
admin_foobar_attribute GET /admin/foobars/:foobar_id/attribute(.:format) admin/foobars#attribute
That is admin_foobar_attribute_path.

Resources