Reputation: 843
Here's my route.rb file:
namespace :api, defaults: { format: 'json' } do
namespace :v1 do
resources :projects, :only => [:index, :create, :update, :destroy, :show] do
resources :events, shallow: true
resources :comments, shallow: true
resources :posts, shallow: true
resources :users, shallow: true
resources :project_participations, shallow: true
end
resources :users, :only => [:show, :index] do
collection do
get :search
post :register_push_receiver_device_id
delete :deregister_push_receiver_device_id
end
end
end
end
When I make request to /api/v1/users/search, this is how the server responds.
Started GET "/api/v1/users/search?search_string=jason" for 127.0.0.1 at 2016-05-13 18:11:02 +0900
Processing by API::V1::UsersController#show as JSON
Parameters: {"search_string"=>"jason", "id"=>"search", "user"=>{}}
User Load (3.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'EMAIL' ORDER BY "users"."id" ASC LIMIT 1
User Load (4.7ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'EMAIL' AND "users"."authentication_token" = 'TOKEN' ORDER BY "users"."id" ASC LIMIT 1
User Load (2.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 0 LIMIT 1
Filter chain halted as :set_user rendered or redirected
Completed 404 Not Found in 70ms (Views: 0.4ms | ActiveRecord: 17.9ms)
As you can see, the request is routed to :show action with 'search' as the id, leading to error.
Interestingly, the request functions fine when I switch the order of projects resources with users resources in the route.rb file.
namespace :api, defaults: { format: 'json' } do
namespace :v1 do
resources :users, :only => [:show, :index] do
collection do
get :search
post :register_push_receiver_device_id
delete :deregister_push_receiver_device_id
end
end
resources :projects, :only => [:index, :create, :update, :destroy, :show] do
resources :events, shallow: true
resources :comments, shallow: true
resources :posts, shallow: true
resources :users, shallow: true
resources :project_participations, shallow: true
end
end
end
In this case, the request is handled correctly.
Started GET "/api/v1/users/search?search_string=jason" for 127.0.0.1 at 2016-05-13 18:21:14 +0900
Processing by API::V1::UsersController#search as JSON
Parameters: {"search_string"=>"jason", "user"=>{}}
User Load (2.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'EMAIL' ORDER BY "users"."id" ASC LIMIT 1
User Load (2.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'EMAIL' AND "users"."authentication_token" = 'TOKEN' ORDER BY "users"."id" ASC LIMIT 1
User Load (80.6ms) SELECT "users".* FROM "users" WHERE "users"."status" = 'member' AND (name LIKE '%jason%') ORDER BY "users"."name" ASC
Rendered api/v1/users/search.json.jbuilder (86.4ms)
Completed 200 OK in 248ms (Views: 90.0ms | ActiveRecord: 99.7ms)
I've read through Rails routing docs but I just can't understand this behavior. Can someone please explain why this is happening??
Upvotes: 0
Views: 162
Reputation: 33542
:users scoped under :projects should not be affecting :users itself!
No, when you run rake routes
, you will see the below route.
user GET /users/:id(.:format) users#show
This is because you have shallow :true
for the resources :users
. This gives you some non-nested routes which includes the show
route as well(which is the one currently troubling you with that issue). so the order matters here.
Upvotes: 1
Reputation: 18454
This is because you have a shallow
route for projects/users
, it defines /api/v1/users/:id
routes.
See your rake routes
Upvotes: 1