概要
表題の通り。
経緯
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を用意して、その中に処理を定義していくしかない...?(あんまりよくわかってない)
おわりに
結局これでやりたいことは実現してしまいました