admin/usersコントローラを作成しようとしたらエラー

restful_authenticationを使っているアプリケーションで、AdminモジュールのUsersコントローラをgeneratorで作成しようとしたら、以下のようにエラーになった。

$ ./script/generate controller admin/users
  The name 'Admin::UsersHelper' is either already used in your application or reserved by Ruby on Rails.
  Please choose an alternative and run this generator again.

'Admin::UsersHelper'はないので、原因が分からない。
restful_authenticationを使っていないアプリケーションで同じことをしたら、大丈夫だった。
次に'Admin::Test'コントローラを作成したら、大丈夫だった。

 $ ./script/generate controller admin/test
      create  app/controllers/admin
      create  app/helpers/admin
      create  app/views/admin/test
      create  test/functional/admin
      create  app/controllers/admin/test_controller.rb
      create  test/functional/admin/test_controller_test.rb
      create  app/helpers/admin/test_helper.rb

'Admin::Test'コントローラを作成してから、'Admin::Users'を作成したら、なぜか大丈夫だった。

$ ./script/generate controller admin/users
      exists  app/controllers/admin
      exists  app/helpers/admin
      create  app/views/admin/users
      exists  test/functional/admin
      create  app/controllers/admin/users_controller.rb
      create  test/functional/admin/users_controller_test.rb
      create  app/helpers/admin/users_helper.rb

'Admin::Test'はいらないので削除。

$ ./script/destroy controller admin/test
          rm  app/helpers/admin/test_helper.rb
          rm  test/functional/admin/test_controller_test.rb
          rm  app/controllers/admin/test_controller.rb
    notempty  test/functional/admin
    notempty  test/functional
    notempty  test
       rmdir  app/views/admin/test
    notempty  app/views/admin
    notempty  app/views
    notempty  app
    notempty  app/helpers/admin
    notempty  app/helpers
    notempty  app
    notempty  app/controllers/admin
    notempty  app/controllers
    notempty  app

よく分からないけど、とりあえずこれでOKだったので、メモしておく。

config.gemについて

[Edge Rails] Gemの管理を行う: Gem Dependencies | poqu.log
Ruby On Rails ピチカート街道 - Rails 2.1・その10(gemの依存関係を明示的に指定) -
config.gemで何ができるかについて。
パッケージ名とライブラリ名が異なっている場合は:libなどで正しく指定する必要がある。

config.gem "rmagick", :lib => "RMagick"

Yano lablog - RMagickのインストール for Ubuntu and Rails

rails2.1.0でgettextのエラー

$ ./script/server -b 127.0.0.1
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails 2.1.0 application starting on http://127.0.0.1:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 127.0.0.1:3000
** Starting Rails with development environment...
Exiting
/Users/pistolfly/railsprojects/test/app/controllers/application.rb:7: undefined method `init_gettext' for ApplicationController:Class (NoMethodError)
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in `load_without_new_constant_marking'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in `load_file'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:214:in `load_file'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:95:in `require_or_load'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:60:in `depend_on'
	from /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:456:in `require_dependency'
	from /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:18:in `define_dispatcher_callbacks'
	 ... 40 levels...
	from /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/commands/server.rb:39
	from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
	from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `require'
	from ./script/server:3

とりあえずエラーが発生しているApplicationController(application.rb)のinit_gettextをコメントアウトしてmongrelを起動して、ページにアクセスすると、今度は以下のエラー。

  Status: 500 Internal Server Error
  undefined method `file_exists?' for #
    /Library/Ruby/Gems/1.8/gems/gettext-1.91.0/lib/gettext/rails.rb:281:in `render_file'
    /Library/Ruby/Gems/1.8/gems/gettext-1.91.0/lib/gettext/rails.rb:279:in `each'
    /Library/Ruby/Gems/1.8/gems/gettext-1.91.0/lib/gettext/rails.rb:279:in `render_file'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/rescue.rb:181:in `rescue_action_locally'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/rescue.rb:125:in `rescue_action'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/rescue.rb:203:in `perform_action_without_caching'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/caching/sql_cache.rb:13:in `perform_action'
    /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/query_cache.rb:33:in `cache'
    /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/lib/active_record/query_cache.rb:8:in `cache'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/caching/sql_cache.rb:12:in `perform_action'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:529:in `send'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:529:in `process_without_filters'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/filters.rb:569:in `process_without_session_management_support'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/session_management.rb:130:in `process'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:389:in `process'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:149:in `handle_request'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:107:in `dispatch'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:104:in `synchronize'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:104:in `dispatch'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:120:in `dispatch_cgi'
    /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:35:in `dispatch'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `process'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `each'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:in `run'
    /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:502:in `load'
    /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/commands/servers/mongrel.rb:64
    /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
    /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `require'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in'
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require'
    /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/commands/server.rb:39
    /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
    /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `require'
    ./script/server:3

対処方法は以下のページに。
rails2.0.2 → 2.1.0 に移行 - 夜の Discovery
Edge Rails and gettext: undefined method file_exists? (NoMethodError)
config/initializers/gettext.rbを作成する。
内容は以下。

require 'gettext/rails'
module ActionView
  class Base
    delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
  end
end

config/initializers/gettext.rbにgettext/railsのrequireを書いたので、config/environment.rbから、gettext/railsの読み込みを削除。

# config/initializers/gettext.rbに移動
#require 'gettext/rails'

この問題は、Rails-2.0.xからRails-2.1.0でActionView::Base#file_exists? メソッドが ActionView::TemplateFinder#file_exists?に移ったことが原因らしい。
Ruby-GetText-1.92.0で対応済みなので、上記回避方法は不要となった。
Rails2.1以降では、environment.rbで、require 'gettext/rails'ではなく、config.gemを使う。

require 'gettext/rails'

ではなく、

Rails::Initializer.run do |config|
  :
  :
  config.gem "gettext", :lib => "gettext/rails"
end

Windows サービスを柔軟に管理するサービスマネージャの製作

Windows サービスを柔軟に管理するサービスマネージャの製作:パート1 - japan.internet.com デベロッパー
Windows サービスを柔軟に管理するサービスマネージャの製作:パート2 - japan.internet.com デベロッパー
AppDomain、AppDomainSetupの使用方法が分かるサンプルがある。

// create the service app domain
AppDomain svcDomain = null;
try
{
	AppDomainSetup setup = new AppDomainSetup();
	// use the process base directory as the new domain base and bin path
	setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
	setup.PrivateBinPath = setup.ApplicationBase;
	// use the assembly full name as friendly name
	setup.ApplicationName = asmName.FullName;
	// the base will be the shadow copy 'from' directory
	setup.ShadowCopyDirectories = setup.ApplicationBase;
	// enable shadow copying
	setup.ShadowCopyFiles = "true";
	// create the domain with no CAS evidence
	svcDomain = AppDomain.CreateDomain(asmName.FullName, null, setup);
}
catch (Exception ex)
{
	Logger.LogException(
		new ApplicationException(
			String.Format("Could not create an AppDomain for '{0}'; bypassing that assembly.", 
			asmName.FullName), ex));
	return;
}
// Get remote service handler
RemoteServiceHandler svc = null;
try
{
	// This call will actually create an instance
	// of the service handler in the service domain
	// and return a remoting proxy for us to act on.
	// This is important because we don't want to 
	// load any type info from the service assembly
	// into this assembly
	svc = (RemoteServiceHandler)  
		svcDomain.CreateInstanceFromAndUnwrap(
		svcDomain.BaseDirectory + "\\ServiceBroker.dll", 
		"ServiceBroker.RemoteServiceHandler");
}
catch (Exception ex)
{
	// unload domain
	AppDomain.Unload(svcDomain);
	Logger.LogException(
		new AssemblyLoadException(
			"Could not load ServiceBroker remote service handler, bypassing that file.",
		asmName.FullName, ex));
	return;
}

これは、被管理サービスの実行に使う新しいAppDomainをセットアップするコードです。AppDomainSetupオブジェクトを使用しているのは、AppDomain.CreateDomainのオーバーロードにはないオプションがあるためです。ここでは、ディレクトリプロパティを、現アプリケーションディレクトリを指し示すように設定することと、ファイルのシャドウコピーを作成するよう指示することが重要です。シャドウコピーを作成することによって、アセンブリがアプリケーションディレクトリでロックされることを防止できます。ここで例外がスローされることはまずないと思われますが、それでも、何が起こったかをログに記録するためと、スレッドを例外で終わらせないために、例外を正確にキャッチするようにしました。アプリケーションにユーザインタフェースがないときは、こうやって例外をキャッチし、ログに記録することをお勧めします。