Class: RactorRailsShim::DeviseMappingSnapshot

Inherits:
Object
  • Object
show all
Defined in:
lib/ractor_rails_shim/patches/callables.rb

Overview

Shareable snapshot of a Devise::Mapping. The real Mapping holds an unshareable lambda (failure_app) plus a default-proc Hash (controllers), so it can't be Ractor.make_shareable'd. Request-time code only reads a handful of attributes (name, to/class, router_name, controllers, ...), which are all shareable values. We copy those now (in main) into a frozen Plain Old Object that plays the role of the Mapping in workers.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mapping) ⇒ DeviseMappingSnapshot

Returns a new instance of DeviseMappingSnapshot.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ractor_rails_shim/patches/callables.rb', line 56

def initialize(mapping)
  @name         = mapping.name
  @klass        = mapping.to
  @router_name  = mapping.instance_variable_get(:@router_name)
  @singular     = mapping.instance_variable_get(:@singular)
  @scoped_path  = mapping.instance_variable_get(:@scoped_path)
  @path         = mapping.instance_variable_get(:@path)
  @path_prefix  = mapping.instance_variable_get(:@path_prefix)
  @format       = mapping.instance_variable_get(:@format)
  @sign_out_via = mapping.instance_variable_get(:@sign_out_via)
  @modules      = mapping.modules
  @strategies   = mapping.strategies
  @routes       = mapping.routes
  @used_helpers = mapping.used_helpers
  # controllers is a Hash with a default proc (unshareable) — copy the
  # entries into a plain frozen Hash.
  h = {}
  RactorRailsShim::Funnel.swallow("devise mapping controllers") do
    mapping.controllers.each { |k, v| h[k] = v }
  end
  @controllers = h.freeze
  # failure_app is either Devise::FailureApp (a shareable class) or a
  # lambda (when configured as a String) — keep only the shareable class.
  fa = mapping.instance_variable_get(:@failure_app)
  fa = ::Devise::FailureApp unless fa.is_a?(Class)
  @failure_app = fa
  freeze
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/ractor_rails_shim/patches/callables.rb', line 131

def method_missing(method, *args)
  s = method.to_s
  if s.end_with?("?") && args.empty?
    @modules.include?(s.chomp("?").to_sym)
  else
    super
  end
end

Class Method Details

.generate_predicates_from_devise_modules!Object

Generate an explicit <module>? predicate for every entry in Devise::MODULES, replacing the hardcoded list above. Called at install time (from the devise patch) once Devise is loaded, so the snapshot tracks Devise's actual module set — including any added by third-party gems at boot — instead of a hand-maintained copy. A no-op when Devise::MODULES isn't defined (callables.rb loads before Devise; the hardcoded predicates remain as the fallback). The method_missing fallback still handles modules added later via Devise.add_module after this generator ran.



149
150
151
152
153
154
155
156
157
# File 'lib/ractor_rails_shim/patches/callables.rb', line 149

def self.generate_predicates_from_devise_modules!
  return unless defined?(::Devise::MODULES)
  ::Devise::MODULES.each do |m|
    next if method_defined?("#{m}?")
    module_eval <<-RUBY, __FILE__, __LINE__ + 1
      def #{m}?; @modules.include?(:#{m}); end
    RUBY
  end
end

Instance Method Details

#authenticatable?Boolean

Returns:

  • (Boolean)


100
# File 'lib/ractor_rails_shim/patches/callables.rb', line 100

def authenticatable?; @modules.any? { |m| m.to_s =~ /authenticatable/ }; end

#confirmable?Boolean

Returns:

  • (Boolean)


117
# File 'lib/ractor_rails_shim/patches/callables.rb', line 117

def confirmable?;              @modules.include?(:confirmable);              end

#controllersObject



98
# File 'lib/ractor_rails_shim/patches/callables.rb', line 98

def controllers; @controllers; end

#database_authenticatable?Boolean

Explicit x? predicates for Devise's standard module set (devise-5.x/lib/devise/modules.rb). Defining these as real methods makes the message-based contract visible — a reader can see which predicates the snapshot answers without grepping Devise, and method_defined? returns true for them. Each returns true iff the module Symbol is in @modules, matching the generated Devise::Mapping#x? behaviour exactly.

Returns:

  • (Boolean)


111
# File 'lib/ractor_rails_shim/patches/callables.rb', line 111

def database_authenticatable?; @modules.include?(:database_authenticatable); end

#failure_appObject



99
# File 'lib/ractor_rails_shim/patches/callables.rb', line 99

def failure_app; @failure_app; end

#formatObject



92
# File 'lib/ractor_rails_shim/patches/callables.rb', line 92

def format; @format; end

#fullpathObject



102
# File 'lib/ractor_rails_shim/patches/callables.rb', line 102

def fullpath; "/#{@path_prefix}/#{@path}".squeeze("/"); end

#lockable?Boolean

Returns:

  • (Boolean)


118
# File 'lib/ractor_rails_shim/patches/callables.rb', line 118

def lockable?;                 @modules.include?(:lockable);                 end

#modulesObject



94
# File 'lib/ractor_rails_shim/patches/callables.rb', line 94

def modules; @modules; end

#nameObject



85
# File 'lib/ractor_rails_shim/patches/callables.rb', line 85

def name; @name; end

#no_input_strategiesObject



101
# File 'lib/ractor_rails_shim/patches/callables.rb', line 101

def no_input_strategies; @strategies & Devise::NO_INPUT; end

#omniauthable?Boolean

Returns:

  • (Boolean)


113
# File 'lib/ractor_rails_shim/patches/callables.rb', line 113

def omniauthable?;             @modules.include?(:omniauthable);             end

#pathObject



90
# File 'lib/ractor_rails_shim/patches/callables.rb', line 90

def path; @path; end

#path_prefixObject



91
# File 'lib/ractor_rails_shim/patches/callables.rb', line 91

def path_prefix; @path_prefix; end

#recoverable?Boolean

Returns:

  • (Boolean)


114
# File 'lib/ractor_rails_shim/patches/callables.rb', line 114

def recoverable?;              @modules.include?(:recoverable);              end

#registerable?Boolean

Returns:

  • (Boolean)


115
# File 'lib/ractor_rails_shim/patches/callables.rb', line 115

def registerable?;             @modules.include?(:registerable);             end

#rememberable?Boolean

Returns:

  • (Boolean)


112
# File 'lib/ractor_rails_shim/patches/callables.rb', line 112

def rememberable?;             @modules.include?(:rememberable);             end

#respond_to_missing?(method, _) ⇒ Boolean

Fallback for custom modules added via Devise.add_module by third-party gems. The standard set is handled by the explicit methods above; anything else falls through here, answering x? predicates by checking @modules — matching the generated Devise::Mapping.add_module behaviour for non-standard modules.

Returns:

  • (Boolean)


127
128
129
# File 'lib/ractor_rails_shim/patches/callables.rb', line 127

def respond_to_missing?(method, _)
  method.to_s.end_with?("?") || super
end

#router_nameObject



87
# File 'lib/ractor_rails_shim/patches/callables.rb', line 87

def router_name; @router_name; end

#routesObject



96
# File 'lib/ractor_rails_shim/patches/callables.rb', line 96

def routes; @routes; end

#scoped_pathObject



89
# File 'lib/ractor_rails_shim/patches/callables.rb', line 89

def scoped_path; @scoped_path; end

#sign_out_viaObject



93
# File 'lib/ractor_rails_shim/patches/callables.rb', line 93

def sign_out_via; @sign_out_via; end

#singularObject



88
# File 'lib/ractor_rails_shim/patches/callables.rb', line 88

def singular; @singular; end

#strategiesObject



95
# File 'lib/ractor_rails_shim/patches/callables.rb', line 95

def strategies; @strategies; end

#timeoutable?Boolean

Returns:

  • (Boolean)


119
# File 'lib/ractor_rails_shim/patches/callables.rb', line 119

def timeoutable?;              @modules.include?(:timeoutable);              end

#toObject



86
# File 'lib/ractor_rails_shim/patches/callables.rb', line 86

def to; @klass; end

#trackable?Boolean

Returns:

  • (Boolean)


120
# File 'lib/ractor_rails_shim/patches/callables.rb', line 120

def trackable?;                @modules.include?(:trackable);                end

#used_helpersObject



97
# File 'lib/ractor_rails_shim/patches/callables.rb', line 97

def used_helpers; @used_helpers; end

#validatable?Boolean

Returns:

  • (Boolean)


116
# File 'lib/ractor_rails_shim/patches/callables.rb', line 116

def validatable?;              @modules.include?(:validatable);              end