1
votes

I keep recieving this error while trying to login to my rails app using devise:

No route matches [PATCH] "/users/sign_in"

I cannot for the life of me figure out why the sign in is not working with the devise gem. My routes are as follows:

              Prefix Verb   URI Pattern                    Controller#Action
                root GET    /                              static_pages#home
    new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
        user_session POST   /users/sign_in(.:format)       devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
       user_password POST   /users/password(.:format)      devise/passwords#create
   new_user_password GET    /users/password/new(.:format)  devise/passwords#new
  edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
                     PATCH  /users/password(.:format)      devise/passwords#update
                     PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
   user_registration POST   /users(.:format)               devise/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
                     PATCH  /users(.:format)               devise/registrations#update
                     PUT    /users(.:format)               devise/registrations#update
                     DELETE /users(.:format)               devise/registrations#destroy
                home GET    /home(.:format)                static_pages#home
               about GET    /about(.:format)               static_pages#about
             lessons GET    /lessons(.:format)             lessons#index
                     POST   /lessons(.:format)             lessons#create
          new_lesson GET    /lessons/new(.:format)         lessons#new
         edit_lesson GET    /lessons/:id/edit(.:format)    lessons#edit
              lesson GET    /lessons/:id(.:format)         lessons#show
                     PATCH  /lessons/:id(.:format)         lessons#update
                     PUT    /lessons/:id(.:format)         lessons#update
                     DELETE /lessons/:id(.:format)         lessons#destroy

I see that PATCH /users/sign_in is not a route, but I can't figure out why it isn't created by devise_for :users? I was under the impression such call would generate all the necessary routes for basic authentication.

EDIT 1:

/app/views/devise/sessions/new.html.erb

<h2>Log in</h2>

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password, autocomplete: "off" %>
  </div>

  <% if devise_mapping.rememberable? -%>
    <div class="field">
      <%= f.check_box :remember_me %>
      <%= f.label :remember_me %>
    </div>
  <% end -%>

  <div class="actions">
    <%= f.submit "Log in" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>
2
What if you explicitly add method: :post to form_for ?. If you remove your template and uses the default happens the same thing?Alter Lagos

2 Answers

2
votes

We are having exactly the same issue. So far, the best solution I have found is to create routes for patch requests like this:

as :account do
  patch '/accounts/sign_in', to: 'accounts/sessions#create'
end

Note, that our resource_name is account and we have inherited from the session controller of rails, therefore the controller 'accounts/sessions'.

Edit: A better solution is to change your form to always create a new session like this:

The original code from the devise tutorial to customize the sign in view:

<%= form_for(:user, :url => session_path(:user)) do |f| %>

Change it into the new action and use a post request:

<%= form_for(:user, :url => new_session_path(:user), :method => :post) do |f| %>
1
votes

Why can't you just POST to create a new session? As shown in your routes:

   user_session POST   /users/sign_in(.:format)       devise/sessions#create