Ruby-GetText-Packageだけというわけではないですが、app/controllers/application.rbで何かを行う*1gemを使っているとrake gems:installで足りないgemをインストールできません。経験したことがあるけど別に手動でインストールすればいいやということで、おそらく、わりとうやむやにされていることが多い問題ではないでしょうか。
例えば、Ruby-GetText-Packageだと以下のようにapp/controllers/application.rbを変更する必要があります。
1 2 3 |
class ApplicationController < ActionController::Base init_gettext "blog" end |
Ruby-GetText-Packageのgemがない場合は「init_gettext」が定義されていないため「NameError」が発生します。そのため、rake gems:installをしようとすると以下のように失敗してしまいます。
% rake gems:install (in /tmp/blog) rake aborted! undefined method `init_gettext' for ApplicationController:Class (See full trace by running task with --trace)
これを回避するために「足りないgemがあるときはinit_gettextを使わない」という方法があります。 あまりきれいな方法ではありませんが、紹介します。
1 2 3 4 5 |
class ApplicationController < ActionController::Base if Rails.configuration.gems.reject {|gem| gem.loaded?}.empty? init_gettext "blog" end end |
もし、config/environment.rbでconfig.active_record.observersを指定しているなどして、app/model/以下も読み込まれるのであれば、ダミーのN_を定義しておくとよいでしょう。
1 2 3 4 5 6 7 8 9 |
class ApplicationController < ActionController::Base if Rails.configuration.gems.reject {|gem| gem.loaded?}.empty? init_gettext "blog" else class ActiveRecord::Base def self.N_(*args); end end end end |
これでRuby-GetText-Packageを使っているときでもrake gems:installが動くようになります。
% rake gems:install (in /tmp/blog) gem install gettext Bulk updating Gem source index for: http://gems.rubyforge.org/ Successfully installed gettext-1.93.0 1 gem installed Installing ri documentation for gettext-1.93.0... Installing RDoc documentation for gettext-1.93.0...
以下、「足りないgemがあるとき」の判断方法について少し書いてみます。
Railsでは「足りないgemがあるかどうか」を示すAPIを提供しているのはRails::Initializerです。ただ、残念ながらconfig/environment.rbの中で作ったRails::Initializerはどこにも保存されていないので、無理やり引っ張り出す必要があります。具体的には以下のようなコードになります。
1 2 3 4 5 6 |
initializer = nil ObjectSpace.each_object(Rails::Initializer) do |object| initializer = object break end initializer.gems_dependencies_loaded |
しかし、この方法ではRails::InitializerがGCされてしまっていると動きません*2。
また、ObjectSpaceはできれば使いたくないものです。そのため、もう少し安全で、何をしているのかがまだわかりそうな方法の方がよさそうです。そのための「足りないgemがあるかどうか」を判断する方法が以下のようになるというわけです。
1 |
Rails.configuration.gems.reject {|gem| gem.loaded?}.empty?
|
ただ、この方法はRails 2.1.2(や2008-10-30でのmaster)では動きますが、もし、Rails内部の「足りないgemがあるかどうか」を判断する方法が変わった場合は動かなくなる可能性もあります。 「あまりきれいな方法ではありませんが」と書いたのはこのためです。
Ruby-GetText-Packageを使っている場合でもrake gem:installを利用する方法を紹介しました。
同じような問題は他のライブラリでも起こりうると思うので、そのような場合も同じように問題を回避できると思います。