0

私はこの要件に取り組んでいます。エンティティが非常に強くリンクされている、非常に大きなオブジェクトリレーショナルモデルがあります。例として、この関係を使用してみましょう。建物には多くのアパートがあり、アパートには多くの区画があります。さて、私が欲しいのは、ある部門で何かが変更されたときに、建物に「通知」するか、建物が「更新」または「変更」されたことをマークすることです。

  • 現在の解決策:部門を「影響を与える」建物としてマークし、部門が更新されるたびに建物の「変更された」タイムスタンプが更新される、自作の実装があります。

  • 望ましい解決策:既存の「すぐに使える」実装(gem、プラグイン、神など)。これにより、実装のリファクタリングの作業を省くことができます。

  • 望ましくない解決策:これらすべての関連付けを:autosave=>trueでマークするように言わないでください。キューに入れられるソリューションが欲しいのですが。

もちろん、目的のソリューションを含まないが、現在のソリューションのパフォーマンスを改善するための提案であるソリューションも歓迎します。望ましい解決策がない場合は、既存の解決策を確実に改善します。

小さな編集:

この動作は一般的である必要があります。これは建物の場合だけでなく、関連付けのあるモデルでもこの​​動作をすることができます。これは常に同じです。影響を受ける関連付けをフェッチして更新します。今、私は同じルーチンで異なるオブザーバーを書きたくありません。

パフォーマンスの問題について:影響を受けるアソシエーションの更新を更新すると、影響を受けるアソシエーションもトリガーされる必要があります。ここで、1つの建物が100の区画に影響を与え、各区画が100の椅子に影響を与えると想像してみましょう。現在、オブザーバーソリューションはビジネスレベルでのみ機能します。つまり、オブザーバーが行動できるように、すべてのARインスタンスをインスタンス化する必要があります。私はこれを悪いパフォーマンスとして保持しています。Aが100Bに影響する場合、1つのDBステートメントでそれを行います。しかし、SQLを使用してすべてを実行すると、これらの100のオブザーバーをどのようにトリガーできますか?

したがって、主な更新ポイントに戻ります。この動作は一般的であり、最も重要なのは、パフォーマンスが最高である必要があることです(たとえば、アソシエーションによって、has_manyアソシエーションのnxn更新がトリガーされる場合があります)。

4

2 に答える 2

3

を使用できますobserveraudit_observer.rb次の名前でファイルを作成しますapp/models

class AuditObserver < ActiveRecord::Observer
  observe :division

  def after_update(division)
    division.logger.info('Division is updated at #{division.updated_at}')
    ######Your logic goes here 
  end
end
于 2012-10-23T15:07:44.247 に答える
0

それで、私がそれを解決する方法は、オブザーバーデザインパターンの実装に関するさまざまな提案の混合でした。したがって、最初に、パターンの基本的な実装はどれも私には機能しません。なんで?モデルAがその関係Bを観察し、Bがその関係Aによって観察され、この観察のルーチンが別の場所で(それをそれと呼ぶことにします)通知機能で定義されるという概念が欲しかったのです。

Rubyの「オブザーバー」ライブラリを使用できなかったのはなぜですか?理論的にはそれを達成できたかもしれませんが、観察されたオブジェクトは「changed」と呼ばれるメソッドを呼び出してオブザーバーに通知します。「changed」はActiveRecord、つまり「ダーティ」ライブラリによって上書きされるメソッドです。

ARの「オブザーバー」を使用できなかったのはなぜですか?ここでオブザーバーは私が通知者になりたいものだからです。ルーチンはモデルに実装されていませんが、他のどのARモデルに通知する必要があるかはわかりませんでした。これは邪魔でした。

どうやって解決したの?ActiveModel :: Observingライブラリを使用して自分でライブラリを作成しました。これにより、必要な機能を実装できました。私はこのDSLを持つように設計しました:

クラスA<ActiveRecordhas_one:b

 observes :b, :on => :create, :notifiers => :update_observer

終わり

つまり、bが作成されると、bとaに到達してそれを使用して何かを実行できるnotifierupdate_observerがあります。したがって、この場合:

class UpdateObserverNotifier < Notifier

  def action(observable, observer)
    observer.update_attributes(updated_at: observable.updated_at)
  end
end

オブザーバーへのDSL呼び出しは、それぞれのクラスに「オブザーバー」と「オブザーバブル」の動作を注入します。Notifier基本クラスには通知動作があり、オブザーバブルからの何かをオブザーバーにミラーリングする必要がある場合に備えて、オブザーバブルとオブザーバーオブジェクトの両方にアクセスできます。また、アクションがオブザーバーでコールバックをトリガーすると、オブザーバー自体の潜在的なオブザーバーにも通知されます。

うん、これでした。提案をありがとう、そうでなければ私はそれを達成しなかっただろう。

于 2012-11-16T16:02:06.117 に答える