2012-01-16 2 views
1

私はバスデポをモデル化するコードを書いています。どのようにhas_manyが常に「最小値」を持つことを保証しますか?

バスの各fleetには常に少なくとも1つのbusがあります。私はこの最小限の数値をモデルに適用する最善の方法を見つけ出す必要があります。艦隊の最後のバスは、艦隊そのものが破壊されていない限り、破壊することはできません。

1つの方法は、busオブジェクトの関係をキャプチャすることです。

class Bus 
    ... 
    before_destroy :check_minimum_busses_on_parent 
end 

しかし、これは単一責任の原則を広く無視しています。バスは問題ではない艦隊の問題に取り組んでいます。

代わりにbefore_destroyメソッドを使用してbus_observerを作成することができます。すべてが今や単一責任であり、必要以上に多くの物体が揺れ動いているように感じます。

class BusObserver < ActiveRecord::Observer 
    def before_destroy bus 
    false if bus.fleet.busses.count <= 1 
    end 
end 

これは確かに仕事を行いますが、私はそれが本当に所属Fleetクラスからデカップリング約100%満足していません。艦隊は親fleetオブジェクト自体が破壊され、それは私も結局、最後のバスを取り除きたいかもしれないという可能性を可能にするために、その最後のバス

を破壊するためにまだ許可

class BusObserver < ActiveRecord::Observer 
    def before_destroy bus 
    if bus.fleet.busses.count <= 1 
     false unless bus.fleet.currently_being_destroyed? 
    end 
    end 
end 

これは明らかに純粋な醜さのレルムを入力している:バスは艦隊のは、あまりにもチョップを取得するかどうかを把握することができますので、いくつかのクロス通信を必要とします。艦隊オブジェクトに座っている方法.bus_can_be_destroyed?にそれを書き込むことができますが、それはずっと良いことではありません。

私が最後のものを得る最もクリーンな方法は何ですか?

答えて

1

バスを指定すると、ビジネスロジックを適切に処理するDecommissionerクラスがありますか?これは明らかで合理的です。

デコミッショニングイベントのロギングに興味がある場合は、ActiveRecordモデルであってもかまいません。線に沿って

何か:

class BusDecommissioner 
    def initialize(bus) 
    @bus = bus 
    end 
    def decommissionable? 
    @bus.fleet.buses.size > 1 
    end 
    def decommission! 
    @bus.destroy if decommissionable? 
    end 
end 
+0

廃炉を定義することもできます。メソッドを使用して_fleet.decommission!(bus)_を呼び出すことができます。 –

1

はそれがAssociation callbacksで動作しますか?ドキュメントによれば、before_removeコールバックを使用して削除を停止することができます。

+0

私はこれがまさに私が探しているものだと思います。実験後に確認します –

+0

このコールバックを使用した経験はありますか?私はそれを作ることができない:http://stackoverflow.com/questions/8893877/why-isnt-before-remove-firing-in-this-has-many-association/8894085#8894085 –

+1

いいえ、私はしていないそれを自分で試しました。私はドキュメントの中でそれを見つけて、あなたの問題に答えることができると思った。 githubのソースコードを参照しようとしましたが、何も見つかりませんでした。だから、削除された可能性があります:-( –