Person
とAdministrator
という2つのRailsモデルがあります。私たちは、モデルレベルでAdministrator
秒の除去を禁止している:スーパークラスメソッドを呼び出すためにインスタンス上で単一のメソッドを再定義
class Person < ActiveRecord::Base
end
class Administrator < Person
def destroy
raise "Can't remove administrators."
end
end
me = Administrator.new
me.destroy # raises an exception
私はテスト中にこの問題を回避できるようにしたいと思いますが、唯一のセットアップとティアダウン中に作成された特定のインスタンスのために。私はクラスの振る舞いを変更したくないので、class_eval
とremove_method
は実行できません。
def me.destroy
super
end
またはシングルトンクラスでそれを再定義:
は、私が実際のインスタンスの#destroy
メソッドを再定義しようとした
class << me
def destroy
super
end
end
をしかしそれらはまだ例外が発生しました。スーパークラスメソッドを暗黙的に呼び出す方法を理解できませんでした。
def destroy!
ActiveRecord::Persistence.instance_method(:destroy).bind(self).call
end
シングルを指示する任意の簡単な方法があります:私は一種のクラスの動作を変更することなく、私の願望に違反し、(それが実際のActiveRecordのメソッドではありませんので)私自身のdestroy!
メソッドを作成することになりましたスーパークラスメソッドを呼び出すインスタンスメソッド?
最終回答:ホルガーちょうどにリンクされて、私は単純に明示的にスーパークラスのメソッドを呼び出すことができた記事に基づいて:
def me.destroy
self.class.superclass.instance_method(:destroy).bind(self).call
end
ありがとう、ホルガー。あなたの提案は素晴らしいですが、私は 'super 'への私の呼び出しがスーパークラスメソッドを呼び出すことに失敗した理由がほとんど不思議です。それがなぜ起こるかあなたは何か考えがありますか? – Brandan
あなたの構造では、あなたの 'me'インスタンスのシングルトンクラス(eigenclassとも呼ばれる)にオーバーライドされたdestroyメソッドを作成しました。あなたがそのメソッドのスコープ内にいる場合、スーパーチェーンは次のようになります:eigenclass - > class - >モジュールがクラス - >親クラスに含まれています...これはあなたの 'destroy'メソッドの' super'呼び出しを'me'はあなたの' Aministrator'クラスの 'destroy'メソッドを呼び出します。固有クラスの概念の詳細については、[この素晴らしい記事](http://blog.madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html)を参照してください。 –
優秀!その記事は私のためにそれをクリアした。 – Brandan