diff --git a/app/controllers/turbo_controller.rb b/app/controllers/turbo_controller.rb new file mode 100644 index 0000000..600e9d2 --- /dev/null +++ b/app/controllers/turbo_controller.rb @@ -0,0 +1,18 @@ +class TurboController < ApplicationController + class Responder < ActionController::Responder + def to_turbo_stream + controller.render(options.merge(formats: :html)) + rescue ActionView::MissingTemplate => error + if get? + raise error + elsif has_errors? && default_action + render rendering_options.merge(formats: :html, status: :unprocessable_entity) + else + redirect_to navigation_location + end + end + end + + self.responder = Responder + respond_to :html, :turbo_stream +end diff --git a/app/controllers/users/devise_controller.rb b/app/controllers/users/devise_controller.rb new file mode 100644 index 0000000..c3aafd5 --- /dev/null +++ b/app/controllers/users/devise_controller.rb @@ -0,0 +1,18 @@ +class Users::DeviseController < ApplicationController + class Responder < ActionController::Responder + def to_turbo_stream + controller.render(options.merge(formats: :html)) + rescue ActionView::MissingTemplate => error + if get? + raise error + elsif has_errors? && default_action + render rendering_options.merge(formats: :html, status: :unprocessable_entity) + else + redirect_to navigation_location + end + end + end + + self.responder = Responder + respond_to :html, :turbo_stream +end diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb index 6b68ee6..9e4c6b5 100644 --- a/app/views/devise/shared/_error_messages.html.erb +++ b/app/views/devise/shared/_error_messages.html.erb @@ -2,7 +2,7 @@
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index b75750f..91efcee 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -3,6 +3,21 @@ require 'digest' require 'securerandom' # frozen_string_literal: true +# Create custom failure for turbo +class TurboFailureApp < Devise::FailureApp + def respond + if request_format == :turbo_stream + redirect + else + super + end + end + + def skip_format? + %w(html turbo_stream */*).include? request_format.to_s + end +end + # Assuming you have not yet modified this file, each configuration option below # is set to its default value. Note that some are commented out while others # are not: uncommented lines are intended to protect your configuration from @@ -44,6 +59,7 @@ Devise.setup do |config| # ==> Controller configuration # Configure the parent class to the devise controllers. # config.parent_controller = 'DeviseController' + config.parent_controller = 'TurboController' # ==> Mailer Configuration # Configure the e-mail address which will be shown in Devise::Mailer, @@ -289,6 +305,7 @@ Devise.setup do |config| # # The "*/*" below is required to match Internet Explorer requests. # config.navigational_formats = ['*/*', :html] + config.navigational_formats = ['*/*', :html, :turbo_stream] # The default HTTP method used to sign out a resource. Default is :delete. config.sign_out_via = :get @@ -302,10 +319,11 @@ Devise.setup do |config| # If you want to use other strategies, that are not supported by Devise, or # change the failure app, you can configure them inside the config.warden block. # - # config.warden do |manager| - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end + config.warden do |manager| + manager.failure_app = TurboFailureApp + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + end # ==> Mountable engine configurations # When using Devise inside an engine, let's call it `MyEngine`, and this engine