Module#unloadableメソッド

developmentモードで動かすと、自作pluginのviewに対してアクセスすると初回は問題ないが、2度目にアクセスすると
A copy of ApplicationController has been removed from the module tree but is still active!
などというメッセージとともにArgumentErrorが発生する。production環境だと発生しない。今のところ原因がよくわからない。
(追記)
http://d.hatena.ne.jp/tomisima/20090126/1232994598
に書いてあるようにcontrollerでunloadableを呼ぶとエラーは起きなくなる。つか公式サイトのプラグイン作成チュートリアルにも書いてあった。ちゃんと読もう > 自分

A copy of ApplicationController has been removed from the module tree but is still active!

っていうエラーは、プラグインでApplicationControllerが存在することを前提としたコントローラを作って、developmentモードで動かした場合、1度目のアクセスでは必要なコントローラ群がロードされるけど、そのコントローラへの2回目のアクセスでは、ApplicationControllerは再ロードされ、古いApplicationControllerクラス(Classクラスのインスタンス)は破棄されて使えないはずなんだけど、リロード対象外のプラグインにあるコントローラがそれを参照しているので、「その古いクラスはもうリロードされてるからそいつを参照している奴がいるのはおかしいよ」と言ってるようです。

なので、unloadableメソッドで自身をアンロード可能にしておいて、developmentモードで2回目のアクセスがあったとき?にアンロード/ロードをすることによってクラスを作り直して上記のエラーが出ないようにする必要がある訳です。実際unloadableメソッドの呼び出しと一緒にログを書いておくと振るまいが分かると思います。

class PluginEmbeddedController < ApplicationController
  unloadable

  logger.debug("#{self.name} loaded!")

id:maedanaさんが書かれている通り、RedmineのPlugin Tutorialにもその例が書いてありますね。
http://www.redmine.org/wiki/1/Plugin_Tutorial


P.S.
不思議なのは、このunloadableを設定したクラスを覚えておく explicitly_unloadable_constants というモジュール属性へのアクセスを行っている will_unload? メソッドへのアクセスがgrepで見つからないこと。activesupport, actionpack, rails のどこにもない。どこでこれ使ってるんだろう?
http://github.com/rails/rails/blob/master/activesupport/lib/active_support/dependencies.rb#481 なんだけど。うーむ謎。