smellman's Broken Diary

クソみたいなもんです

rake db:migrate RAILS_ENV=production が動かなかった

rake db:migrate RAILS_ENV=production を実行したら、テーブルを作る前なのにいきなりSELECT文発行して落ちるという残念な事になっていた。
原因を調べたところ、rails-2.3.2/lib/initializer.rb の以下のコードが原因だった。

    # Eager load application classes
    def load_application_classes
      return if $rails_rake_task
      if configuration.cache_classes
        configuration.eager_load_paths.each do |load_path|
          matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
          Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
            require_dependency file.sub(matcher, '\1')
          end
        end
      end
    end

ようするに configuration.cache_classes が true だった。確認したら、config/environments/production.rb に以下の記述があった。

config.cache_classes = true

しかしながら、config.cache_classes = false に変更するって手段はあまりよろしくないと思われる。意図して設定しているのに、rake実行時だけ書き変えるのは変でしょう。
というわけで、load_application_classes の $rails_rake_task に注目。ようはこの変数がrake実行時に true になっていればよいというわけだ。
...あれ? なんでこれが初期化されてないんだ?
というわけで、--traceした結果をくままく探してみたところ、lib/tasks/以下にあやしいファイルを発見。
ファイルを覗いてみると、先頭の方に以下のような記述を確認。

require File.dirname(__FILE__) + "/../../config/environment"

...rakeが初期化される前に読み込んだらだめやろー
というわけで、このタスク自体必要か聞いて削除OKとの事だったので、削除したところ無事db:migrateが通りました。やったー。
まぁ、なんというか、すごく残念な感じですね。