どのような問題が起きるのか
config/environments/development.rb など
config.eager_load = false
が指定された環境で STI のサブクラスなどは親のクラスを呼んでもロードされません。
class Animal < ApplicationRecord
end
class Cat < Animal
end
class Dog < Animal
end
rails c で確認すると
irb(main):001:0> Animal.subclasses
=> []
このようにサブクラスは空になります。
何故なのか
config.eager_load が false だからなのですが、もう少し詳しく説明すると eager_load を使わない環境ではクラスが呼ばれたタイミングでロードを行うためです。
なので config/environments/development.rb に
require_relative "../../app/models/cat"
require_relative "../../app/models/dog"
と書くと一見うまく動きそうですが Ruby の require は 1 回読んだファイルは再ロードしないため初回しかうまくいきません。
例えばビューに
<% Animal.subclasses.each do |animal| %>
<%= animal.new.type %>
<% end %>
と書いて rails s でサーバを起動すると、一度アクセスしたページをリロードした際などにサブクラスが表示されなくなると思います。
どうすればいいのか
require_dependency を使います。これは Rails が提供しており、何度でもファイルの読み込みを行ってくれます。
require_dependency "cat"
require_dependency "dog"
class Animal < ApplicationRecord
end
確認のためにサブクラスに適当なメソッドを用意します。
class Cat < Animal
def cry
"うみゃみゃ"
end
end
ビューを変更して適宜確認してみます。
<%= Cat.new.cry %>
一度「うみゃみゃ」が表示される事を確認したらモデルのファイルを書き換えます。
class Cat < Animal
def cry
"騒ぐほどでもないか"
end
end
更新を保存してサーバをリロードすると「騒ぐほどでもないか」に表示が変更されると思います。