downcase_keysメソッドを読む。
# test/models/authenticatable_test.rb:51
# 追記
class AuthenticatableTest < ActiveSupport::TestCase
...
test 'downcase_keysを試す' do
user = User.create!(email: 'EXAMPLE@example.com', password: '1234567')
assert_equal user.email, 'example@example.com'
end
end
$ bin/test test/models/authenticatable_test.rb:51
# app/config/boot.rb
require 'bundler/setup'
# lib/devise.rb
module Devise
mattr_accessor :case_insensitive_keys
@@case_insensitive_keys = [:email]
end
require 'devise/models' # 538
# lib/devise/models.rb
module Devise
module Models
...
end
end
# config/initializers/devise.rb ( lib/generators/templates/devise.rb )
Devise.setup do |config|
require 'devise/orm/active_record' # 39
config.case_insensitive_keys = %i(email gmail) # 61 (動作確認用に置換した)
end
# lib/devise/orm/active_record.rb
ActiveSupport.on_load(:active_record) do
extend Devise::Models
end
class User < ApplicationRecord < ActiveRecord::Base
devise :database_authenticatable
end
# lib/devise/models.rb:79
module Devise
module Models
def devise(*modules)
...
include Devise::Models::Authenticatable
...
end
end
end
# lib/devise/models/authenticatable.rb:67
module Devise
module Models
module Authenticatable
extend ActiveSupport::Concern
...
included do
...
before_validation :downcase_keys
...
end
end
end
end
# lib/devise/models/authenticatable.rb:198
module Devise
module Models
module Authenticatable
def downcase_keys
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
end
end
end
end
# lib/devise/models/authenticatable.rb:198
user.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
↓
User.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
# lib/devise/models/authenticatable.rb:221
module Devise
module Models
module Authenticatable
extend ActiveSupport::Concern
...
module ClassMethods
Devise::Models.config(self, ... , :case_insensitive_keys, ...)
end
end
end
end
# lib/devise/models.rb:31
module Devise
module Models
def self.config(mod, *accessors) #:nodoc:
# 関係ない class << mod; attr_accessor :available_configs; end
# 関係ない mod.available_configs = accessors
accessors.each do |accessor|
mod.class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{accessor}
if defined?(@#{accessor})
@#{accessor}
elsif superclass.respond_to?(:#{accessor})
superclass.#{accessor}
else
Devise.#{accessor}
end
end
def #{accessor}=(value)
@#{accessor} = value
end
METHOD
end
end
end
end
# ( lib/devise/models/authenticatable.rb:198 )
module Devise
module Models
module Authenticatable
def downcase_keys
[:email, :gmail].each { |k| apply_to_attribute_or_variable(k, :downcase) }
end
end
end
end
# lib/devise/models/authenticatable.rb:206
module Devise
module Models
module Authenticatable
def apply_to_attribute_or_variable(attr, method)
if self[attr]
self[attr] = self[attr].try(method)
# Use respond_to? here to avoid a regression where globally
# configured strip_whitespace_keys or case_insensitive_keys were
# attempting to strip or downcase when a model didn't have the
# globally configured key.
# 追記 これは仮想の属性用の分岐
elsif respond_to?(attr) && respond_to?("#{attr}=")
new_value = send(attr).try(method)
send("#{attr}=", new_value)
end
end
end
end
end