Devise do not generate rails standard URL - ruby-on-rails

I have this setup for Devise
devise_for :users, :controllers => {
:confirmations => "confirmations",
:registrations => "registrations"} do
put "confirm_user", :to => "confirmations#confirm_user"
end
and when I run
rake route
I have get strange routes for registrations_controller specialy the edit_path
edit_user_registration GET /users/edit(.:format) registrations#edit
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
The problem is edit url for example for first user.
I expected
/users/1/edit
but I have get
/users/edit.1
I expect this route can not work but it does. Now I am not sure if I have made some mistake or if the devise generate the routes this way.
And if it generate routes that way where goes the format of request?
I can not believe that the URL might look like this.
/users/edit.1.js
Thanks for any advise?

The issue is not related to the edit url, instead it depends on the page that is linking to the edit one. You have probably a link of this form
link_to "Settings", edit_user_registration_path(#user)
that point to the edit url, which generates the unexpected url
/users/edit.id
You simply have to replace the link omitting the #user, as
link_to "Settings", edit_user_registration_path

That . is always there when showing a format. It's nothing from Devise, and there's nothing wrong with it. You're all good!

I am passing the id to the edit route but it doesn't expect an id.
The edit_user_registration_path is only for current_user so the user.id is unnecessary.
This question might be also helpful.
Devise: Allow admins to edit other users - Rails

Related

Rails model_path routing error, no route matching "model.2"; should be "model/2"

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 (i.e. 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.

Undefined Method in Devise Routes with User ID

Currently I have a typical devise installation but I've added user-id's to the routes that have a current_user available. But I'm getting the error stated below when trying to login to the service.
Error
NameError in Devise::SessionsController#create
undefined local variable or method `offers_path' for #<Devise::SessionsController:0x007f0e80ec7a08>
def after_sign_in_path_for(resource)
offers_path
end
routes.rb
devise_for :users
resources :users do
resources :offers do
member do
put :tourcomplete
end
end
end
Rake Routes
tourcomplete_user_offer PUT /users/:user_id/offers/:id/tourcomplete(.:format) offers#tourcomplete
user_offers GET /users/:user_id/offers(.:format) offers#index
POST /users/:user_id/offers(.:format) offers#create
new_user_offer GET /users/:user_id/offers/new(.:format) offers#new
edit_user_offer GET /users/:user_id/offers/:id/edit(.:format) offers#edit
user_offer GET /users/:user_id/offers/:id(.:format) offers#show
PATCH /users/:user_id/offers/:id(.:format) offers#update
PUT /users/:user_id/offers/:id(.:format) offers#update
DELETE /users/:user_id/offers/:id(.:format) offers#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
Not too sure if this is the best way to put user-id's within the logged in routes. Would love any help on this issue.
Seeing your routes, you don't have any offers_path but you are trying to use that, that's why you are getting this error.
You should try using user_offers_path instead and the pass the user as the argument, something like this:
user_offers_path(#user)

Devise Registration URL could not be found

I have a problem with devise after customizing the signup - route.
The devise doc mentions, that routes can easily be customized, so I tried to add a token to the URL to set up a easy invitation system. Ist really straight forward and all I did was adding
devise_for :users, :path_names => { :sign_up => "signup/:invitation_token" }
to my routes. A mailer sends an email with the token and inside I pass
new_user_registration_path(#invitation.token)
rake routes says
new_user_registration GET /users/signup/:invitation_token(.:format) devise/registrations#new
But I'm still getting
No route matches {:action=>"new", :controller=>"devise/registrations", :locale=>:de, :invitation_token=>nil}
I get it wether I pass the token or not...
I'm not shure what I'm missing.
Thanks in advance, hope someones sees what I'm doing wrong.
Greets, Rob
Check #invitation.token to make sure that it's not nil.
The error you're witnessing will occur on any view in which you pass nil into your new_user_registration_path link tag.
Bear in mind that you'll need to override the default behavior of Devise's users/registration controller in order to get your invitation system working correctly. Something like this would work:
# routes.rb
devise_for :users, :path_names => { :sign_up => "signup/:invitation_token" }, :controllers => {:registrations => "users/registrations"}
# app/controllers/users/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
# add custom create logic here
end
end

Devise edit_account_password action redirects me to the root

Here are my devise routes:
devise_for :accounts, :path_names => { :sign_up => "new" } do
get "sign_in", :to => "devise/sessions#new"
get "sign_out", :to => "devise/sessions#destroy"
get "/change_password", :to => "devise/passwords#edit"
end
And the output of my rake routes:
account_password POST /accounts/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
new_account_password GET /accounts/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
edit_account_password GET /accounts/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
PUT /accounts/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
So the change_password route is not in place and /change_password just redirects me to the root_path. Please help me understand why or I will hurt myself. Thank you.
Okay, im figured out the problem. Edit password is from Recoverable module, it aims to help the user to get his/her password back if its forgotten, and not for a signed in user to change his/her password. You can use registration/edit instead.
I wasn't sure if you were talking about behavior after a user changes his password through the above-mentioned routed change password action. If you are, please consider this question and answer which may either answer your question or give you a heads up for what you may encounter:
Devise logging out automatically after password change

Rails resourceful routes all point to index action?

I'm runnng Rails 2.3.8.
I set up map.resources :users in my routes.rb file.
When I run rake routes it shows:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
GET /users(.:format) {:action=>"index", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"index", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"index", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
/:controller/:action/:id
/:controller/:action/:id(.:format)
Sorry about the formatting. But the point is... 1) where are my "PUT", "POST", etc. routes?, 2) Why does everything point to index??
Any help would be much appreciated... Thanks!
UPDATE: Full routes file:
ActionController::Routing::Routes.draw do |map|
map.login "login", :controller => "user_sessions", :action => "new"
map.logout "logout", :controller => "user_sessions", :action => "destroy"
map.resources :users
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
And my users_controller has all the usual new, create, show, edit, update methods...
I think you have one of two problems: either the output from rake routes has been mangled by your terminal screen, or your routes are being overridden by something else you installed, like a rails engine.
The first is easy to check for. it sounds like you have a basic user scaffold setup (and not much else) so fire up script/server, go to http://localhost:3000/users/new. If you see the new user page, you have a terminal display issue, but your routes are fine. If you see the users index page, however, proceed to the next step.
Double-check that the routes file you posted above is indeed the file for your app. This sounds ridiculous, but in some editors it's easy to open the wrong file. In TextMate for example, if you have some gems vendored and open the routes file via command-T, you can have multiple routes.rb files to choose from.
If you're sure you're viewing the correct routes file, the next step is to check your application for any other routes.rb files that may be overriding your main file. From terminal, you can run find ./ -name routes.rb and this will list any other routes files. This is especially likely if you have any rails engines installed.
Let me know how this goes - if you're still having problems, you can zip your application and e-mail it to me, and I'll take a look.

Resources