heartcombo / devise

Flexible authentication solution for Rails with Warden.
http://blog.plataformatec.com.br/tag/devise/
MIT License
23.89k stars 5.54k forks source link

some Devise 4.9.0 interface glitches Rails 7 Turbo — SOLVED: always use `.html` format specifier in filenames #5564

Closed jasonfb closed 1 year ago

jasonfb commented 1 year ago

I am trying out the new 4.9.0 on a new Rails 7 app but I am still getting errors with the sign up form. Specifically, the old sign up form appears stuck on the screen even though the action is successful.

Steps to reproduce:

Setup a new app:

APP_NAME=DeviseTest1 && rails new $APP_NAME --javascript=esbuild --database=postgresql && CURRENT_NODE=$(nvm current) && cd $APP_NAME && echo $CURRENT_NODE >> .node-version && echo "Node + Ruby versions are in \`.node-version\` and \`.ruby-version\`, respectively.\n\n# Setup\n\n\`./bin/setup\`\n\n# Start Rails\n\n\`./bin/dev\`\n\n# Run Specs\n\nrun with \`./bin/rake\`" > README.md && git add . && git commit -m "initial commit with $(rails -v), Node $CURRENT_NODE, Ruby $(more ./.ruby-version)" && sed -i '' -e 's/ruby-//g' .ruby-version && RUBY_STRING="ruby \"$(more ./.ruby-version)\"" && sed -i '' -e "s/$RUBY_STRING/ruby File.read('.ruby-version').strip/g" Gemfile  && git add . && git commit -m "fixes .ruby-version file and sets Gemfile to use .ruby-version file" && ./bin/setup && git add . && git commit -m "adds schema file"

Make a basic home page:

rails generate controller Welcome &&
sed -i '' -e 's/class WelcomeController < ApplicationController/class WelcomeController < ApplicationController\n  def index\n\n  end/g' app/controllers/welcome_controller.rb &&
echo "hello world" > app/views/welcome/index.erb &&
sed -i '' -e  's/# root "articles#index"//g' config/routes.rb && 
sed -i '' -e  's/Rails.application.routes.draw do/Rails.application.routes.draw do\n  root to: "welcome#index"/g' config/routes.rb && git add . && git commit -m "generates Welcome controller"

Install devise:

bundle add devise && bundle install && 
git add . && git commit -m "adding devise gem" && 
rails generate devise:install && 
git add . && git commit -m 'devise install' &&
sed -i '' -e  's/Rails.application.configure do/Rails.application.configure do\n  config.action_mailer.default_url_options = { host: "localhost", port: 3000 }/g' config/environments/development.rb && 
git add . && git commit -m 'devise setup' 

Generate the user:

rails generate devise User name:string && rails db:migrate && git add . && git commit -m "generating devise user"

Start the server with ./bin/dev

Go to http://127.0.0.1:3000/users/sign_up

Input test username & password

Monosnap DeviseTest1 2023-03-02 10-56-44

Click "Sign Up"

Current behavior

Monosnap DeviseTest1 2023-03-02 10-54-05

here's what the Rails log says: Monosnap DeviseTest1 — esbuild ◂ foreman: master NVM_INC=:Users:jason: nvm:versions:node:v16 17 1:include:node MANPATH=:Users:jason: nvm… 2023-03-02 10-53-50

Expected result: • The signup form goes away and the user is correctly taken to the home page

Environment

carlosantoniodasilva commented 1 year ago

Thanks for the detailed steps. I tried reproducing quickly but apparently I'm running into some issue with esbuild/node/yarn or something along those lines, so I'll need more time to tinker with it.

What I can say for now is that running a stock Rails app with import maps worked fine, that's my current test app that I used to validate everything. I'll try this some more and see if I can get things running properly and learn anything.

jasonfb commented 1 year ago

this might be at the intersection of Turbo's behavior. notice than the home page content gets appended outside the \<body> tag, very strange:

Monosnap DevTools - 127 0 0 1:3000:users:sign_up 2023-03-02 11-24-27

jasonfb commented 1 year ago

@carlosantoniodasilva -- ok no problem there's no rush. I was just hoping I could stop sticking in the data-turbo: false into all of my devise forms now. It's probably something small. @driftingruby (Dave Kiruma) said that just doing the exact steps above he was able to reproduce, but also he has an example app using JSBundling/CSSBundling and Devise 4.9.0 that he shared with me that does not show the symptom at all.

He & I compared our example apps, and we can't tell what's different, so it's a puzzel.

Here's Dave's example app (working), using JSBundling/CSSBundling and Devise 4.9.0 :

example.zip

(it happens to have data-turbo: false in the views, but if you take those off, it still works)

Here's my (with symptom) app, which you can regenerate easily using the above git commands:

https://github.com/jasonfb/DeviseTest1

will keep this open as we continue to investigate root cause.

carlosantoniodasilva commented 1 year ago

@jasonfb I may have found the issue here: the view is named index.erb, and renaming it to include the format: index.html.erb appears to work: (not that I added the flash message and a sign out button to the layout to help testing)

https://user-images.githubusercontent.com/26328/222555510-0b39d06d-19ce-48b1-9a33-9def550e7899.mp4

I also checked Dave's example app and it's view is index.html.erb, which explains why that one worked and this example did not.

Here are the logs and screenshots of the response:

With the view as index.erb: it renders only the view and not the layout (because it's a turbo_stream request I believe)

18:10:48 web.1  | Started POST "/users/sign_in" for ::1 at 2023-03-02 18:10:48 -030e
18:10:48 web.1  | Processing by Devise::SessionsController#create as TURBO_STREAM
18:10:48 web.1  |   Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"carlos@test.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
18:10:48 web.1  |   User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["email", "carlos@test.com"], ["LIMIT", 1]]
18:10:48 web.1  | Redirected to http://localhost:3000/
18:10:48 web.1  | Completed 303 See Other in 265ms (ActiveRecord: 0.2ms | Allocations: 2796)
18:10:48 web.1  |
18:10:48 web.1  |
18:10:48 web.1  | Started GET "/" for ::1 at 2023-03-02 18:10:48 -0300
18:10:48 web.1  | Processing by WelcomeController#index as TURBO_STREAM
18:10:48 web.1  |   Rendering welcome/index.erb
18:10:48 web.1  |   Rendered welcome/index.erb (Duration: 0.0ms | Allocations: 7)
18:10:48 web.1  | Completed 200 OK in 0ms (Views: 0.2ms | ActiveRecord: 0.0ms | Allocations: 298)

All we get back is the content of that index.erb view: Screenshot 2023-03-02 at 18 09 12

With the view as index.html.erb, it will detect use the HTML format from the view and render the matching layout too.

18:09:53 web.1  | Started POST "/users/sign_in" for ::1 at 2023-03-02 18:09:53 -0300
18:09:53 web.1  | Processing by Devise::SessionsController#create as TURBO_STREAM
18:09:53 web.1  |   Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"carlos@test.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
18:09:53 web.1  |   User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["email", "carlos@test.com"], ["LIMIT", 1]]
18:09:54 web.1  | Redirected to http://localhost:3000/
18:09:54 web.1  | Completed 303 See Other in 265ms (ActiveRecord: 0.2ms | Allocations: 2522)
18:09:54 web.1  |
18:09:54 web.1  |
18:09:54 web.1  | Started GET "/" for ::1 at 2023-03-02 18:09:54 -0300
18:09:54 web.1  | Processing by WelcomeController#index as TURBO_STREAM
18:09:54 web.1  |   Rendering layout layouts/application.html.erb
18:09:54 web.1  |   Rendering welcome/index.html.erb within layouts/application
18:09:54 web.1  |   Rendered welcome/index.html.erb within layouts/application (Duration: 0.0ms | Allocations: 7)
18:09:54 web.1  |   User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
18:09:54 web.1  |   ↳ app/views/layouts/application.html.erb:15
18:09:54 web.1  |   Rendered layout layouts/application.html.erb (Duration: 3.5ms | Allocations: 3123)
18:09:54 web.1  | Completed 200 OK in 4ms (Views: 3.6ms | ActiveRecord: 0.1ms | Allocations: 3370)

And we get back a full page, including the body with the index.html.erb content rendered:

Screenshot 2023-03-02 at 18 08 56

I'm guessing that because we don't get a full page back, Turbo is apparently doing that weird thing that you saw where the content ended up below the "body" tag.

I hope that helps, let me know if you run into anything else that might be Devise related.

jasonfb commented 1 year ago

@carlosantoniodasilva — Confirmed, that was it. Years and years ago (like 15), 'they' told me I no longer need .html specifier because it would be inferred as default— you know, back when the web was simpler. And so I picked up a bad habit, which I will now unlearn. Thank you so much, this is indeed solved

carlosantoniodasilva commented 1 year ago

@jasonfb thanks for confirming.

Yeah, I do remember / know it's not supposed to inferred, I'm just not sure if there's some weird interaction between Turbo and it's new format/handling, being able to render the view but not the layout, because on first page load it works, but not on the turbo request.

Anyway, glad we figured it out, and that it's not Devise related. :)