Rails routes index for nested resource - ruby-on-rails

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.

Related

Ruby on Rails - How to add a second route for the same action?

I have this route:
resources :posts do
resources :comments
end
A post can be a "User Message" showed at:
/posts
A post can be a "News" showed at:
/news
How can I create the "/news" url inside the routes.rb file and pass a param for know inside the post controller the type of post I want?
This way you can declare routes which can not be declared using resources.
get '/news' => 'posts#index', as: :news

How to write routes right in Ruby-on-Rails?

In my routes.rb file, I have the following code:
Rails.application.routes.draw do
get 'getTodos', to: 'todos#get'
get 'getUsers', to: 'users#get'
get 'getStates', to: 'states#get'
post 'addTodo', to: 'todos#add'
post 'addUser', to: 'users#add'
delete 'deleteTodo/*id', to: 'todos#delete'
delete 'deleteUsers/*IDs', to: 'users#delete'
delete 'deleteAllTodos', to: 'todos#delete_all'
put 'updateTodo', to: 'todos#update'
end
How can I modify this code to make it more beautiful and correct?
The biggest issue with this code is that its completely unidiomatic. In Rails you create, read, update and destroy (CRUD) resources through the following routes:
HTTP Method Path Controller#Action
GET /todos(.:format) todos#index
POST /todos(.:format) todos#create
GET /todos/new(.:format) todos#new
GET /todos/:id/edit(.:format) todos#edit GET /todos/:id(.:format) todos#show
PATCH /todos/:id(.:format) todos#update
PUT /todos/:id(.:format) todos#update
DELETE /todos/:id(.:format) todos#destroy
The key here is the combination of the HTTP method and path.
GET /todos gets you all the todos while GET /todos/:id shows you a specific resource.
GET /todos/new displays the form to create a new todo. POST /todos actually creates the resource from a form submission.
GET /todos/:id/edit displays the form to edit a todo. PATCH /todos/:id actually updates the resource from a form submission.
DELETE /todos/:id - You should be able to guess what this does.
You can generate these routes with:
Rails.application.routes.draw do
resources :todos
end
If you want to define a routes that deletes all the todos RESTfully it should be defined as DELETE /todos (without an id).
Rails.application.routes.draw do
resources :todos do
delete '/', on: :collection, action: :destroy_all
end
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
See:
Rails Routing from the Outside In
I would do something like this. Try to use default Rails REST actions instead of overwriting them
Rails.application.routes.draw do
resources :todos, only: [:index, :create, :update, :destroy] do
collection do
delete :delete_all, to: 'todos#delete_all'
end
end
resources :users, only: [:index, :create, :destroy]
resources :states, only: :index

No route matches [PUT], resource and method are defined though

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.

Rails nested resources and paths

in my routes.rb I have:
resources :boards do
resources :items
end
now in boards#show I want to show a link to http://mysite/baord/:board_id/items/new, running rake routes I get:
new_board_item GET /boards/:board_id/items/new(.:format) items#new
and so I should be able to use new_board_item_path but this works only from site.com/board/:board_id/items but i want to use this link in boards#show action but it tells me that:
No route matches {:action=>"new", :controller=>"items"}
while that's not true!
Pass the parent resource into the path, so in this case:
new_board_item_path(#board)

Changing the route behaviour but keeping the "Convention over Configuration"

I am using Ruby on Rails 3.0.7 and in my application I have an Users::Article class (note that it is namespaced). In the routes.rb file it is stated as follow:
resources :users do
resources :articles
end
I would like to set the route related to the Users::Article class so that I can access that at the URL /articles, /articles/new, /articles/1 and /articles/1/edit but I would like to still use the RoR Convention over Configuration "system". That is, I would like to use:
Users::ArticlesHelper;
views/users/articles/<file_name>.html.erb view files;
named routes (<name>_path and <name>_url);
and others "a là Ruby on Rails Way"...
How can I do that?
In few words, for example, I would like to refer to the /articles/1 path but making the application to work exactly as it is considering the users/<user_id>/articles/1 path.
it's not an estetic matter, but it's related to parameters for routing.
you can use /articles/:id and then refer to the owner (User) inside controller.
in the second case /users/:user_id/articles/:id will pass 2 params to controller.
From the ActionDispatch::Routing::Mapper::Resources docs:
:shallow
# Generates shallow routes for nested resource(s). When placed on a parent
# resource, generates shallow routes for all nested resources.
resources :posts, :shallow => true do
resources :comments
end
# Is the same as:
resources :posts do
resources :comments, :except => [:show, :edit, :update, :destroy]
end
resources :comments, :only => [:show, :edit, :update, :destroy]
# This allows URLs for resources that otherwise would be deeply nested such as a
# comment on a blog post like /posts/a-long-permalink/comments/1234 to be
# shortened to just /comments/1234.
To get this from >rake routes
users_articles GET /articles(.:format) {:action=>"index", :controller=>"users/articles"}
POST /articles(.:format) {:action=>"create", :controller=>"users/articles"}
new_users_article GET /articles/new(.:format) {:action=>"new", :controller=>"users/articles"}
edit_users_article GET /articles/:id/edit(.:format) {:action=>"edit", :controller=>"users/articles"}
users_article GET /articles/:id(.:format) {:action=>"show", :controller=>"users/articles"}
PUT /articles/:id(.:format) {:action=>"update", :controller=>"users/articles"}
DELETE /articles/:id(.:format) {:action=>"destroy", :controller=>"users/articles"}
We need this in our routes.rb
namespace :users, :path => '' do
resources :articles
end
Note: I am using :namespace as that is what you stated.
Hope this helps.

Resources