There seems to be something wrong with my routing paths. Normally I should be able to do something like <%= link_to Profile, user_path(@user||current_user) %>
and I move on with my day. For whatever reason I'm failing to understand my user_path
is not returning /user/:id
like I would expect it to do. Instead it is returning /user.:id
To test this, I loaded a partial with the following code.
app/view/users/_test.html.rb
<%= @user %><br>
<%= @user.id %><br>
<%= link_to user_path(@user), user_path(@user) %><br>
<%= new_user_path %><br>
<%= edit_user_path(@user) %><br>
<%= url_for(@user) %>
This returned
localhost:3000/test
#<User:0x007fb6cd341f08>
1
/user.1
/users/new
/users/1/edit
/user.1
I can't figure out what is causing this to happen. The edit_user_path(@user)
works perfectly, but the show doesn't. I have read the Rails Routing Guide from top to bottom about three times and I can't figure it out. The closest I found to my problem was on an old Rails 3.1 gem problem with Devise , but I'm not even using the Devise gem (maybe I should be?).
Why is my route failing? I'm not really looking for a workaround (though I suppose I'd rather have a workaround than no solution), I want to understand why this is happening and fix it. What's going on?
My routes are pretty vanilla, nothing special going on there, but just in case the problem is there and I missed it, here it is.
config/routes.rb
Rails.application.routes.draw do
root 'static#home'
%w( 404 406 422 500 503 ).each do |code|
get code, :to => "errors#show", :code => code
end
#USER PAGES
get '/test' => 'users#test'
get '/signup' => 'users#new'
post '/user' => 'users#create'
get '/user/list' => 'users#index'
post '/user/' => 'users#update'
get '/user/:id' => 'users#show'
get 'profile', to: 'users#show'
resources :users
end
I'd suggest updating your routes as follows:
config/routes.rb
Rails.application.routes.draw do
root 'static#home'
%w( 404 406 422 500 503 ).each do |code|
get code, :to => "errors#show", :code => code
end
#USER PAGES
get '/test' => 'users#test'
get 'profile', to: 'users#show', as: :user_profile
resources :users
end
...as resources :users
creates all of the routes I've removed.
The duplicates may have been overwriting a default path, causing the behaviour you're seeing - if you pass an object to a url helper that doesn't expect a parameter, you see the behaviour you're getting (ie doesnt_have_an_id_path(@object) => /doesnt_have_an_id.1
).
I've also added a name to the user profile path to avoid this clashing. See if this works (perhaps one step at a time to get the cause and effect) - otherwise, try temporarily removing the profile route.
Re that path, you may have a problem in that the users#show
action will expect an :id
parameter, yet that route doesn't allow for one. This might be causing the current problem, though if not, may cause issues down the line.
Hope that fixes it - shout if you've any questions / feedback when you've tried it out.
In your case the two conflicting routes are:
post '/user/' => 'users#update'
get '/user/:id' => 'users#show'
You are trying to use user_path
helper method, thus you need to have user
named route. If you run rake routes
for these two routes you will see this:
Prefix Verb URI Pattern Controller#Action
user POST /user(.:format) users#create
GET /user/:id(.:format) users#show
The Prefix
column shows you the named routes which are defined for your application. In this case Rails auto-generated named route user
for POST /user
endpoint. That means user_path
will return /user instead of /user/:id
as you expected. Rails generate routes like these when it sees a route definition without parameters. For example if you have get /user/some/more
in your routes, Rails will auto-generate named route user_some_more
for you and they you will be able to use user_some_more_path
helper.
In order to fix your particular case you can stop rails from generating route for POST endpoint by doing this: post '/user/', as: nil
and give GET endpoint a name you want: get '/user/:id', as: 'user'
. Then you will be able to use user_path(user)
to generate paths of format /user/:id.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.