All threads / How to use Devise with Hotwire & Turbo.js Discussion

Ask A Question

Notifications

You’re not receiving notifications from this thread.

How to use Devise with Hotwire & Turbo.js Discussion

Hey Chris - If we are still using Webpacker, we just need to change data-turbolinks-track to data-turbo-track in our layout files? In your episode repo, you still have it as turbolinks.

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>

<%= turbo_include_tags %>

<%= stimulus_include_tags %> if we want to use stimulus in webpacker?

Reply

Hey Chris, this is super amazing. I'm using hotwire-rails and there's 2 errors that need your expertise:

  • The TurboController gives an error undefined local variable or methodturbo_include_tags'`
  • When the redirect on incorrect password happens, it doesn't show 'notice'

turbo_include_tags is not necessary. for the second issue, make sure that you have config.navigational_formats = ['*/*', :html, :turbo_stream] on your devise.rb

I also ran in to this issue. If you could add this line to the source code it would be much better for people trying to follow along.

Matias, thanks for saving me! :)

Reply

Your video arrived just in time, thanks !
But I have a blocking issue implementing this solution:
undefined local variable or methodturbo_include_tags'`

I had the same issue. Loading issue concerning application controller.

I put the turbo controller in the controllers dir in turbo_controller.rb and issue was resolved

Also confirmable not longer works when you remove <%= turbo_include_tags %> from the header. And the “turbo_frame_tag” form will no longer show when you run a frame on a page. And you get routing error when you try to log out a session.

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

I can also confirm that creating a ./app/controllers/turbo_controller.rb instead of adding it to the top of the devise.rb initializers fixed my undefined local variable or method 'turbo_include_tags' error.

This also worked for me. Thanks Jay.

Reply

Hi Chris, seems you forgot to include the line about config.navigational_formats in the snippet which was shown in the screencast

Reply

Correct me if i'm wrong but the one of disadvantages of this method is that on new session page if user typed wrong email and submits the form the email will not be preserved due to this lines:

    if request_format == :turbo_stream
      redirect

I found more appropriate solution for me how to fix this.

  1. do not override respond method.
  2. add data-turbo="false" attribute to sign in form (which you should copy in advance)

Check this commit for this new feature:

https://github.com/hotwired/turbo/commit/ea00632e9790a680c7704d90101403f34d9433a6#diff-38acdd502c97ee1a1140d761a08c7e07e46c9f266b4efd0c55d0d5b986517158R40

Reply

For the login form, now I use Turbo instead of Turbolinks I have 401 response (because of TURBO_STREAM type ?)

Processing by Devise::SessionsController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"username"=>"alex", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms | Allocations: 372)

I'm getting this same error on the login form. The registration form works correctly. I'm using "@hotwired/turbo-rails": "^7.0.0-beta.5",

From what I can tell, Chris has also updated the source code for this episode to use beta.3. Not sure what I'm doing wrong here.

Reply

Thank you Chris! I can't make works errors render, notice works well. Any ideas? 🤔

Reply

Seems to me a like hacky ... will wait to implement this in a production project, login form handling have to be very basic stuff.

Reply

Any easy way to get this to work with the 'hotwire-rails' gem?

upgraded to beta .3 and its working

Reply

I've got a few devise controllers I've inherited from ( to add some breadcrumbs, etc). They don't like the turbocontroller.
Do I also need to inherit that as well?

Reply

Has anyone tried to destroy a user on devise via account edit user page?

I get undefined method `users_url' for #Devise::RegistrationsController:0x0000000000ca58
on line --> redirect_to navigation_location

whenever I try to do so.

I had the same error and I solved with this
config.navigational_formats = ['/', :html, :turbo_stream] in devise.rb

Thanks Gonzaa, I had exactly this problem and that line solves it.

Reply

If you're getting a

ActionView::Template::Error (undefined method `turbo_frame_tag' ...

in Production, make sure to set

config.parent_controller = 'Users::DeviseController'

and extract the

class TurboController < ApplicationController
...
end

into app/controllers/users/devise_controller.rb.
See also the hotwire-devise Repo for the source code!

Reply

I'm getting an error undefined methodthen' for "messages":Stringon my<%= turbo_stream_from "messages" do %>` line in an app I'm trying to build this into. Any ideas why?

Reply

when one logs into to a rails app using devise & turbo. how does the csrf token get updated on the page. I get Can't verify CSRF token authenticity. error when I send a from with turbo after a turbo login

Reply

If, like me, you rushed through this video and are now are seeing the error from warden Invalid strategy some_external_strategy ... it could be because you uncommented the entire block in devise.rb initializer file. I didn't want to post this comment because I might look silly but... in case someone else makes my mistake :D

config.warden do |manager|
    manager.failure_app = TurboFailureApp
    # manager.intercept_401 = false
    # manager.default_strategies(scope: :user).unshift :some_external_strategy
  end

and not

config.warden do |manager|
    manager.failure_app = TurboFailureApp
    manager.intercept_401 = false
    manager.default_strategies(scope: :user).unshift :some_external_strategy
  end
Reply

Hello.
Has anyone managed to use the "current_user" method from Devise in broadcasted partial views?

I have merged the 2 applications "hotwire-devise" & "hotwire-twitter-clone",
and when I add a call to current_user
(like for instance <%= link_to "Edit", edit_tweet_path(tweet) if current_user.present? %> in the _tweet.html.erb file),
I get an error because the method is not available in this context:

Started POST "/tweets" for 127.0.0.1 at 2021-01-29 14:45:53 +0100
Processing by TweetsController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "tweet"=>{"body"=>"TEST"}, "commit"=>"Create Tweet"}
Tweet Create (0.8ms)  INSERT INTO "tweets" ("body", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["body", "TEST 003"], ["created_at", "2021-01-29 13:45:53.776383"], ["updated_at", "2021-01-29 13:45:53.776383"]]
Rendered tweets/_tweet.html.erb (Duration: 4.3ms | Allocations: 2000)
Completed 500 Internal Server Error in 30ms (ActiveRecord: 19.6ms | Allocations: 5713)

ActionView::Template::Error (Devise could not find the `Warden::Proxy` instance on your request environment.
Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack.
If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.):
 6:       <%= button_to "Likes (#{tweet.likes_count})", tweet_like_path(tweet), method: :post %>
 7:       <%= button_to "Retweets (#{tweet.retweets_count})", tweet_retweet_path(tweet), method: :post %>
 8: 
 9:       <%= link_to "Edit", edit_tweet_path(tweet) if current_user.present? %>
10:     </div>
11:   </div>
12: <% end %>
Reply

consider to separate the TurboController and TurboFailureApp to its own class since put the class inside Devise config could give many much anomalies especially on production because somehow it could ruin your gemfile load order

Reply

There's another issue that seems to exist after the migration. When a user tries to change their password the original password always returns as invalid. Has anyone been able to fix this issue?

Warden also throws an error if you have users credentials expire after an inactivity period.

app/channels/application_cable/connection.rb:13:in `find_verified_user'
There was an exception - UncaughtThrowError(uncaught throw :warden)

Reply

Wouldn't it be simpler to have the devise pages opt out of Turbo via:

Reply

Is using github version still required or bug fix is already merged into master ?

Reply

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

Thank you , that was the solution to the deprecation warning

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'
}

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

devise_scope :user do
authenticated :user do

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

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.

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

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
Join the discussion

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

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

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

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2021 GoRails, LLC. All rights reserved.