No route matches [PUT], resource and method are defined though - ruby-on-rails

I'm using postman to make a PUT or PATCH request, but it says No route matches [PUT] "/api/registrations"
my URL looks like this
http://localhost:3000/api/registrations?id=5&status=approved"
My routes.rb file:
Rails.application.routes.draw do
scope :api do
resources :professors
resources :registrations
resources :schedules
resources :notifications
resources :users
resources :meetings
resources :courses
resources :students
end
end
I have a defined update method in my RegistrationsController and My POST and GET routes work.

The URL you're using is incorrent. You should not pass id in query, but in path.
A correct URL is
http://localhost:3000/api/registrations/5?status=approved
Rails sets id as last element of a resourceful route.
Docs say:
resources :photos
(...)
PATCH/PUT /photos/:id photos#update update a specific photo

Run rails routes on the command line to get the proper URL pattern and it's matching Controller action.

Related

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.

Rails how to make example.com/post/1 to example.com/blog/post/1

I have a blog with root
root 'posts#index'
And works best with example.com/ to example.com/posts
But what I want is something like this:
example.com/blog/posts/1.
I've tried creating blog Controller and add
resources :blog do
resources :posts
end
But this is making my routes to blog/:id/posts/:id
If you don't have the relationship between the post and the blog as you mentioned, rails gives you the freedom to declare routes as our own.
so, to make the route example.com/posts/1 to, example.com/blog/posts/1, just add a custom route at the last.
get '/blog/posts/:id', to: :show, controller: 'posts'
what this does is over rides the previous route and make this route final.
Now type rake routes and it will give the last route for you as,
GET /blog/posts/:id(.:format) posts#show
Now you can access using,
example.com/blog/posts/1
Reference for rails routing
Just to expand upon #Sravan answer. If you have multiple routes that will start with /blog/ you might want to check Rails guide on routing.
You can add something along the lines of
scope '/blog' do
resources :posts
resources :users
resources :images
end
Which will create corresponding routes under /blog/.
namespace :blog do
resources :posts
resources :users
resources :images
end
And your controller with namespace will look like this: Blog::PostsController

Rails 4: routing error under a namespace

In routes.rb:
namespace :account do
resource :groups
resource :posts
end
But I got error when located http://0.0.0.0:3000/account/groups :
***Unknown action
The action 'show' could not be found for Account::GroupsController***
I checked http://0.0.0.0:3000/rails/info/routes and got:
```
account_groups_path POST /account/groups(.:format) account/groups#create
new_account_groups_path GET /account/groups/new(.:format) account/groups#new
edit_account_groups_path GET /account/groups/edit(.:format) account/groups#edit
GET /account/groups(.:format) account/groups#show
PATCH /account/groups(.:format) account/groups#update
PUT /account/groups(.:format) account/groups#update
DELETE /account/groups(.:format) account/groups#destroy
```
Why account/groups not map to index method?
If you'd like to generate only index action then update your route file to restrict the routes created to just index as follows:
namespace :account do
resource :groups, only: [ :index ]
resource :posts
end
The problem however is your resource declaration, you're using singular resource, i.e. resource :groups and resource :posts. What this does is map /account/groups to account/groups#show and account/posts#show. Pluralizing resource will be a better solution:
namespace :account do
resources :groups
resources :posts
end
With this change, running rake routes should provide you the index action you are looking for.

Rails routes index for nested resource

I'm searching a reason why rake routes doesn't match the index path of my nested resource.
Here is my code:
namespace :api do
resources :photos do
resource :comments
end
end
Here is the result of the command: rake routes | grep comment
batch_action_admin_user_comments POST /admin/user_comments/batch_action(.:format) admin/user_comments#batch_action
admin_user_comments GET /admin/user_comments(.:format) admin/user_comments#index
POST /admin/user_comments(.:format) admin/user_comments#create
new_admin_user_comment GET /admin/user_comments/new(.:format) admin/user_comments#new
edit_admin_user_comment GET /admin/user_comments/:id/edit(.:format) admin/user_comments#edit
admin_user_comment GET /admin/user_comments/:id(.:format) admin/user_comments#show
PATCH /admin/user_comments/:id(.:format) admin/user_comments#update
PUT /admin/user_comments/:id(.:format) admin/user_comments#update
DELETE /admin/user_comments/:id(.:format) admin/user_comments#destroy
admin_comments GET /admin/comments(.:format) admin/comments#index
POST /admin/comments(.:format) admin/comments#create
admin_comment GET /admin/comments/:id(.:format) admin/comments#show
api_photo_comments POST /api/photos/:photo_id/comments(.:format) api/comments#create
new_api_photo_comments GET /api/photos/:photo_id/comments/new(.:format) api/comments#new
edit_api_photo_comments GET /api/photos/:photo_id/comments/edit(.:format) api/comments#edit
GET /api/photos/:photo_id/comments(.:format) api/comments#show
PATCH /api/photos/:photo_id/comments(.:format) api/comments#update
PUT /api/photos/:photo_id/comments(.:format) api/comments#update
DELETE /api/photos/:photo_id/comments(.:format) api/comments#destroy
I tried to add only: [:create, :index] to my comments resource but only the create route is visible.
According to the documentation about nested-resources I don't understand what's happening.
Thank you for your help.
It's because you are using a singular resource (resource :comments)
From the docs:
Sometimes, you have a resource that clients always look up without
referencing an ID. For example, you would like /profile to always show
the profile of the currently logged in user. In this case, you can use
a singular resource to map /profile (rather than /profile/:id) to the
show action
You'll need to use the standard resources method to get this working (resource omits the index action):
#config/routes.rb
namespace :api do
resources :photos do
resources :comments
end
end
My mistake. A "S" was missing on my resource.
namespace :api do
resources :photos do
resources :comments
end
end
Now it works.

Adding a restful route like: /users/234/add_section

I already have:
resources :users
How can I add a route (for POST only) that will work like:
/users/2343/add_section
Is it possible to add this route inside of the resources users block?
resources :users do
end
Having add_section there is not very RESTful. Consider having a subresource section and doing POST "/users/123/sections/"
Something like:
resources :users do
member do
post 'add_section'
end
end
As I answered on your previous question
resources :users do
post :add_section, :on => :member
end

Resources