現象
config.eager_load = false
の環境で1ファイル内に複数classを定義した際、ファイル名と異なるclassのautoloadが機能しない
環境
Ruby: 2.3.1
Rails: 4.2.7.1
1ファイル内に複数のclass
source
# app/models/samples/foo.rb
class Samples::SampleError < StandardError; end
module Samples
class Foo
end
end
rails console
config.eager_load = false
> defined? Samples::SampleError
#=> nil
> Samples::SampleError
#=> NameError: uninitialized constant Samples::SampleError
config.eager_load = true
> defined? Samples::SampleError
#=> "constant"
> Samples::SampleError
#=> Samples::SampleError
1ファイル1class
source
# app/models/samples/sample_error.rb
class Samples::SampleError < StandardError; end
# app/models/samples/foo.rb
module Samples
class Foo
end
end
rails console
config.eager_load = false
> defined? Samples::SampleError
#=> nil
> Samples::SampleError
#=> Samples::SampleError
config.eager_load = true
> defined? Samples::SampleError
#=> "constant"
> Samples::SampleError
#=> Samples::SampleError
何が困るか
例えば下記のように、抽象クラスから Samples::Foo
を呼び出すような実装をした際
# app/models/samples/abstract.rb
module Samples
class Abstract
def self.exec
Foo.new.exec
end
end
end
# app/models/samples/foo.rb
class Samples::SampleError < StandardError; end
module Samples
class Foo
def exec
raise SampleError
end
end
end
# spec/models/samples/abstract_spec.rb
require 'rails_helper'
describe Samples::Abstract, type: :model do
describe ".exec" do
it "Samples::SampleErrorが発生する" do
expect { Sample::Abstract.exec }.to raise_error Samples::SampleError
end
end
end
単一ファイルのテストを実行した際、 uninitialized constant Samples::SampleError
が発生する
$ rspec spec/models/samples/abstract_spec.rb
# Randomized with seed 965
#
# Samples::Abstract
# .exec
# Samples::SampleErrorが発生する (FAILED - 1)
#
# Failures:
#
# 1) Samples::Abstract.exec Samples::SampleErrorが発生する
# Failure/Error: expect { Sample::Abstract.exec }.to raise_error Samples::SampleError
#
# NameError:
# uninitialized constant Samples::SampleError
# # ./spec/models/samples/abstract_spec.rb:6:in `block (3 levels) in <top (required)>'
#
# Finished in 0.01472 seconds (files took 3.95 seconds to load)
# 1 example, 1 failure
#
# Failed examples:
#
# rspec ./spec/models/samples/abstract_spec.rb:5 # Samples::Abstract.exec Samples::SampleErrorが発生する
#
# Randomized with seed 965