概要
表題の通り。
経緯
Railsアプリで開発時に初期投入する処理をdb/seeds.rbに書いていた。その際、特定の環境下以外では動作しないように以下のように早期returnする処理を書いていたが、returnだと動かないしexitだと正常な処理終了フローに乗らずに収まりが悪かったので、そもそものタスクの定義箇所から処理を追ってみた。
if !Rails.env.development?
p "Nothing to do."
exit
end
流れ
1. activerecord内にあるrailties/databases.rake
db:seedタスクは以下の箇所にて定義されている。
https://github.com/rails/rails/blob/5-1-stable/activerecord/lib/active_record/railties/databases.rake
railties内のtasks/engine.rakeにもapp:db:seedが定義されているが、これは別物かな...?
2. ActiveRecord::Tasks::DatabaseTasks.load_seed
このmodule DatabaseTasks内に定義されたseed_loader.load_seedをcallしているが、seed_loaderとは何か。
https://github.com/rails/rails/blob/5-1-stable/activerecord/lib/active_record/tasks/database_tasks.rb#L268-L276
seed_loaderはfunctionとしてmodule内に定義されている。
インスタンス変数である@seed_loaderに値をcacheしながら、Rails.applicationを返却している。
https://github.com/rails/rails/blob/5-1-stable/activerecord/lib/active_record/tasks/database_tasks.rb#L102-L104
要はseed_loader.load_seedはRails.application.load_seedを指している。
3. Rails.engine.load_seed
Rails.applicationはRails.engineをextendsしています。Rails.application.load_seedの実体はRails.engineに定義されたRails.engine.load_seedである。
https://github.com/rails/rails/blob/5-1-stable/railties/lib/rails/engine.rb#L543-L550
このfunctionの中で、一番近しいdb/seeds.rbのpathを解決してKernel.loadでそのファイルを読み込んでいる。
4. Kernel.load
第一引数のfileに入力されたpathに沿って、ファイルを読み込むbuilt-in function。
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/load.html
Kernel.loadで読み込んだスクリプトで早期returnするには?
結局これはよくわかんなかった...
loadするRubyスクリプトにblockを用意して、その中に処理を定義していくしかない...?(あんまりよくわかってない)
おわりに
結局これでやりたいことは実現してしまいました![]()