Save 36% for Black Friday! Learn more

Ask A Question

Notifications

You’re not receiving notifications from this thread.

How to use Devise with Hotwire & Turbo.js Discussion

Hello Chris,
Thank you so much for these videos, God bless you.
You saved the day!

Reply

If you receive warning about

DEPRECATION WARNING: Initialization autoloaded the constants ApplicationHelper, FormHelper, Stimulus::StimulusHelper, DeviseHelper, ApplicationController, and ActionText::ContentHelper.

Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.

Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload ApplicationHelper, for example,
the expected changes won't be reflected in that stale Module object.

These autoloaded constants have been unloaded.

In order to autoload safely at boot time, please wrap your code in a reloader
callback this way:

    Rails.application.reloader.to_prepare do
      # Autoload classes and modules needed at boot time here.
    end

That block runs when the application boots, and every time there is a reload.
For historical reasons, it may run twice, so it has to be idempotent.

Check the "Autoloading and Reloading Constants" guide to learn more about how
Rails autoloads and reloads.
 (called from <main> at /home/orlovic/rails/gofordesi-webapp/config/environment.rb:5)

than simply wrap the code inside Rails.application.reloader.to_prepare do like

Rails.application.reloader.to_prepare do
  class TurboFailureApp < Devise::FailureApp
    def respond
      ...
  end
  class TurboController < ApplicationController
      ...
  end
end

Reply

great timing!

Reply

Thank you , that was the solution to the deprecation warning

Reply

I was recieving an error undefined constant ApplicationController and putting those modules inside of this to_prepare block fixed it thank you :))

Reply

I can not log out on Devise!

No route matches [GET] "/users/logout"

routes.rb
devise_for :users, path: 'users',
path_names: {sign_up: 'signup', sign_in: 'login', sign_out: 'logout'},
controllers: {
confirmations: 'users/confirmations',
sessions: 'users/sessions',
registrations: 'users/registrations'
}

Reply

In addition, I have multiple devise model and scope it like below:

devise_scope :user do
authenticated :user do

Reply

I put method: :delete on the logout link_to, but I don't know why it does "GET"

Reply

don't use link_to. user button_to. I removed rails-ujs btw

Reply

I've matched what's in https://github.com/gorails-screencasts/hotwire-devise/ and I'm still not getting 422 Unprocessable Entity's rendered. When submitting an erroneous register form, the server renders the page with the form errors but the client just sits and does nothing. I've inserted a pry into the parent controller and I know that's working well. I've matched versions to "@hotwired/turbo-rails": "7.0.0-beta.3". I'm not sure where the error is or what next to check.

Reply

I still don't know what the problem was but I've followed this comment and got rid of the customizations and rendering a 422 is now working, but rendering a redirect is not. https://github.com/heartcombo/devise/pull/5340#issuecomment-833840004

Reply

Can anybody help? How to deal with hotwire/devise/cancancan - partial problem? If I have a "if can?" in broadcasted partial, I get warden proxy error. "can?" method uses current_user which is not broadcasted.

Reply
Reply

Hey!
I have another problem - when i destroy my account from devise's Account page i see following error:

NoMethodError in Users::RegistrationsController#destroy
undefined method `users_url' for #Users::RegistrationsController:0x0000000002f058
Did you mean?

user_session_url

Rails.root: /Users/alec/Code/Internal/cosmoport
Application Trace | Framework Trace | Full Trace
config/initializers/devise.rb:27:in rescue in to_turbo_stream'
config/initializers/devise.rb:19:in
to_turbo_stream'
app/controllers/application_controller.rb:85:in `configure_time_zone'
Exception Causes
ActionView::MissingTemplate: Missing template users/registrations/destroy, devise/registrations/destroy, devise/destroy, turbo/destroy, application/destroy with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in: * "/Users/alec/Code/Internal/cosmoport/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/blazer-2.4.3/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/devise-i18n-1.10.0/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/bundler/gems/devise-c82e4cf47b02/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/view_component-2.38.0/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/actiontext-6.1.4.1/app/views" * "/Users/alec/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/actionmailbox-6.1.4.1/app/views"

Any idea how to fix it?

Reply

Maybe not the best way, but solving this problem : you can add a new route for users_path :

# config/routes
get '/', to: 'user#index', as: 'users'
Reply

Devise is waiting on the Responders gem to update before having something standard. It pains me, but I've just disabled turbo on devise forms until there's something standard in a released version.

Reply

I had to just disable turbo on the Devise forms as well. I was getting errors and the time spent on figuring those out was too much.

Reply

How did you successfully disable it on your Devise forms? I've tried adding data: { turbo: false } to my registrations/new.html.erb and it doesn't seem to stop processing as turbo_stream.

Reply
<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: {'data-turbo' => "false"}) do |f| %>
Reply

Or just disabling Turbo on all Devise forms and sign out links.

https://turbo.hotwired.dev/handbook/drive#disabling-turbo-drive-on-specific-links-or-forms

Reply

I've got a few devise controllers I've inherited from. They don't like the turbocontroller. Do I also need to inherit that as well?

Reply

Just wanted to mention that for Rails 7, I also needed to change the logout link from using link_to to button_to to make the DELETE request instead of GET.

Reply

You don't have to change the link_to. In devise.rb you change

config.sign_out_via = :delete

to

config.sign_out_via = :get

then in your link_to

<%= link_to destroy_user_session_path, method: :delete %>
Reply

or specify the turbo method like so:

<%= link_to destroy_user_session_path, data: { turbo_method: :delete } %>
Reply

What Tony Serkis suggested really worked for me and my flash messages are being shown correctly on the sign-out action. I have only one question because changing the method to GET request, is there any security concern?

Reply

And for what you suggest Peter, it works, but I'm getting unexpected redirects I think, becuase I see the flash message "You need to sign in or sign up before continue" and that is because it is redirecting me to a controller that is under authentication, maybe I'm doing something wrong:

Started DELETE "/users/sign_out" for ::1 at 2021-12-28 12:09:59 -0600
Processing by Devise::SessionsController#destroy as TURBO_STREAM
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Completed 302 Found in 10ms (ActiveRecord: 0.4ms | Allocations: 5677)


Started DELETE "/" for ::1 at 2021-12-28 12:09:59 -0600

ActionController::RoutingError (No route matches [DELETE] "/"):

Started GET "/dashboard/index" for ::1 at 2021-12-28 12:09:59 -0600
Processing by DashboardController#index as HTML
Completed 401 Unauthorized in 3ms (ActiveRecord: 0.0ms | Allocations: 469)


Started GET "/users/sign_in" for ::1 at 2021-12-28 12:09:59 -0600
Processing by Devise::SessionsController#new as HTML
  Rendering layout layouts/landing.html.erb
  Rendering devise/sessions/new.html.erb within layouts/landing
  Rendered devise/shared/_links.html.erb (Duration: 2.9ms | Allocations: 1300)
  Rendered devise/sessions/new.html.erb within layouts/landing (Duration: 10.9ms | Allocations: 4552)
  Rendered shared/_notifications.html.erb (Duration: 5.5ms | Allocations: 2748)
  Rendered layout layouts/landing.html.erb (Duration: 27.3ms | Allocations: 14853)
Completed 200 OK in 31ms (Views: 29.2ms | ActiveRecord: 0.0ms | Allocations: 16426)
Reply

I had similar issue and it was puzzling me, every time I signup i got redirected to /users which it didn't had any authentication restrictions. Until i notice that I had method: :put for form_for:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name),html: { method: :put, data: { turbo: false } }) do |f| %>

Once I removed method: :put, everything worked nicely.

Reply

FYI, after upgrading to Rails 7 I had to move Chris's TurboController code in this video out of initializers/devise.rb into a normal rails controller to prevent an error when starting the server. I put this code into app/controllers/turbo_devise_controller.rb and then in the devise initializer changed this line to config.parent_controller = 'TurboDeviseController' and everything worked as expected. Thanks to Nick Francisci's article on this here: https://medium.com/@nickfrancisci/devise-auth-setup-in-rails-7-44240aaed4be

Reply

Hey Chris, Im following this tutorial, but having a simple "uninitialized constant ApplicationController (NameError)" for the constant used in your code within devise.rb even though my application_controller is set up. Any ideas what must be the problem. Using Rails 7.

Reply

I recently ran into this as well with Rails 7. Hopefully this will be fixed in Devise soon. For the time being, I just created a new controller that I call in config/initializers/devise.rb like this config.parent_controller = 'TurboDeviseController'.

Here's full devise initializer -> https://gist.github.com/leemcalilly/9d73e1f549d9aa8f2973f5a63004ea32

And here's the new controller (app/controllers/turbo_devise_controller.rb) -> https://gist.github.com/leemcalilly/ab04e30dd8d53429939d7845b5691b83

Reply

Hey Lee! Thanks for the response. I've actually tried that solution, but the errors are still not appearing on failed authentication.

Reply

Actually on signup error messages are working but not on log in. If I type in an incorrect password, no error will appear to the user.

Reply

Found the error, it was how I was using the devide_error_messages template instead of the flash to notify the error. Working already. Thanks Lee

Reply

Hi @Santiago Rodriguez, could you explain better how is this change of devise_error_templateto flash to notify the error on the Login page? I am with the same issue.

Reply

Hey,

i have a problem with sign_in. (Rails7). after users signs in, i get already_authenticated flash message instead of signed_in: "Signed in successfully." any ideas why it happens?

Reply

ok i solved my problem by telling sign_in form to not use turbo :)

<%= form_for(resource, as: resource_name, url: session_path(resource_name), data: { turbo: false }) do |f| %>

Reply

It is a year after this video was made and Devise still does not work with Rails 7. Is there any chance that this will be fixed or do we still need to do all this workaround?

Reply

Basically add the data: { turbo: false }

<%= form_with model: resource, as: resource_name, url: registration_path(resource_name), data: { turbo: false } do |f| %>

Reply

The code in the article worked for me with Rails 7, but I had to do extra steps resolved this issue by adding config.navigational_formats = ['*/*', :html, :turbo_stream] to the initialize/devise.rb and also putting the TurboController in the file app path (app/controller/turbo_controller.rb).

Reply

This post is extremely helpful for me. I really appreciate your kindness in sharing this with me and everyone else!

Reply

Thank you very helpful,

I had this error uninitialized constant users devise and seen in the "Source code for this episode"
app/controllers/Users/devise_controller.rb

Reply

As of 7/18/22, this episode is a good fix for devise. Thanks Chris.

Reply

This has worked quite well for me, with one exception. When changing a password, it ends up calling redirect_to navigation_location but navigation_location is nil at this point.

Reply

The solutions works well. Thank you Chris

The only issue that I'm getting is when I press Enter/Return onKeypress I'm getting this error in console
OnClick event for login or sign out is fine no error in the console.

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 87,110+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.