私は小さなRailsアプリでコードをリファクタリングして重複を取り除き、一般的に私の人生を楽にしています。このリファクタリングの一部は、2つのモデルに共通するコードを、必要な場所に含めることができるモジュールに移動することでした。Rubyミックスとスーパーメソッドを呼び出す
これまでのところ、とても良いです。それはうまくいくように見えるが、私はちょうど私が周りを回避する方法がわからないという問題にヒットしました。モジュール(私はsendableと呼ばれています)は、単にドキュメントのPDFをファックス送信、電子メール送信、または印刷するコードになります。したがって、たとえば、私は発注書を持っており、内部販売注文(想像上ISOと略記)を持っています。
私が打ち砕いた問題は、オブジェクトがロードされた後にいくつかの変数を初期化する(Pの綴りが正しくない人のために初期化される)ので、after_initializeフックを使用しています。問題はありません...ミックスインをもう少し追加するまで。
私が持っている問題は、私は私のミックスインのいずれかでafter_initialize
を持つことができるということですので、私は確かに他のミックスインafter_initialize
コールが呼び出さ作るために開始時にスーパー呼び出しを含める必要があり。私はスーパーに電話するまでは素晴らしいです。電話するスーパーがないので、エラーが発生します。ミックスインのそれぞれがafter_initializeコールを持っている場合、私はどのように停止することができ、スーパーコールで、
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize(params = nil)
super
self.created_at ||= Time.now.to_date
end
end
ので:ここ
は、私は十分に混乱していない場合には、少し例ですその最後の スーパーからの呼び出しエラーを発生させる?私はそれを呼び出す前にスーパーメソッドが存在することをどのようにテストできますか?
Downvoted:ここ
は一例です。あなたがスーパーが存在するかどうか分からないので、ActiveRecord :: Base#after_initializeをmonkeypatchすることで、ActiveRecordがベース#after_initializeを追加するか、またはそのアーリティが変更された場合にコードが壊れるポイントを作成します;それが定義されていれば、それを条件付きで呼び出す方がはるかに良いです。 – yaauie@yaauie - 確かに、monkeypatchの前にmethods.include?(:after_initialize) 'を' raise 'oh noにすることはできましたが、それは例をもっと理解しにくくするでしょう...巻き込まれるのはとても簡単ですここでの実際のレッスン(ちょうどベースメソッドをパッチする)がノイズで失われるというすべてのエッジケースを詳しく説明します。 –
monkeypatchingは一般的な解決策ではなく、一般的には奨励するべきではありません。あなたが継承チェーンを完全に制御することができない場合、*動作する可能性のある一回限りのモンキーパッチを含む答えは、不必要に複雑で脆弱なコードにつながります。 – yaauie