11

モデルの関係を通じて、多くの has_many と has_many を持つモデルがあります。たとえば、私の User クラスには次のものがあります。

has_many :languages, through::profile_languages

User.language_ids= 関数で呼び出されたときに変更された属性の配列を返す「User.changes」関数を使用して、これらがいつ追加または削除されたかを検出できるようにしたいと考えています。

他の誰かがこれをやろうとしたり、これを経験したことがありますか?

ActiveModel 変更機能に関する情報: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

編集:要求に応じて、これが私がやっていることです。

ユーザーの属性が割り当てられた後、それが保存される前に、外部ログに加えられたすべての変更を記録するために、.changes から返されたすべての値を調べています。

したがって、 u.name = "new name" と呼ぶと

u.changes は {name: ['old name', 'new name']} を返します。

ただし、ユーザーに一連の言語 ID を渡すと、次のようになります。

u.language_ids = [4,5]

その後、いくつかの ProfileLanguage モデルが作成され、u.changes ハッシュは空白のままになります。

ProfileLanguage モデルで、ある種のハッシュを手動で作成するコールバックを作成しようとしていますが、これが本当に最善の解決策であるかどうか疑問に思っています。

4

3 に答える 3

15

私が今行っているやや汚い解決策は、コールバックを has_many 関数に追加することです。

has_many :languages, through: :profile_languages, 
        :after_add => :language_add, 
        :before_remove => :language_remove

そして、この情報をカスタム ハッシュに追加します。このハッシュは、.changes 関数を見ているときにプロファイルの保存時にチェックされます。

于 2012-11-09T16:25:13.750 に答える
2

モデルの更新時に新しい関係が作成または削除されたかどうかを確認しようとしていました。

使用してみmodel.relationship.any? { |a| a.changed? }ましたが、これは既存のオブジェクトの変更のみを検出するため、関係の作成と削除には機能しませんでした。

解決策を探していると、問題を解決するこの非常に短い記事を見つけました:リンク

を使用model.select { |a| a.new_record? || e.marked_for_destruction? }.any?して、作成中または破棄中のすべてのレコードを取得できました。

これを組み合わせることa.changed?で、関係のあらゆる変化を得ることができます。

于 2016-05-31T13:13:49.563 に答える
0

テキストベースの変更ログの実装を検討していることは承知していますが、目的paper_trailを達成する方法として、gem を使用して完全なオブジェクトのバージョン管理を検討することをお勧めします。README に従ってこの機能を提供します。

PaperTrail は、Has-One、Has-Many、および Has-Many-Through の 3 種類の関連付けを復元できます。これを行うには、インストール時に rails generate paper_trail:install --with-associations オプションを使用して、または手動で version_associations テーブルを作成する必要があります。PaperTrail は、関連付けられたレコードが変更されたときに、関連付けのバージョンとモデルのバージョンを関連付けるために、そのテーブルに追加情報を格納します。

の has-many-through 機能を使用したことはありませんがpaper_trail、関連付けのないオブジェクトに使用したことがあり、優れていて実装が簡単であることがわかりました。

テキスト ファイル ログとこのデータベース ペーパー トレイルを作成するには、paper_trail の diff 機能after_saveコールバックで使用できます。

于 2016-06-01T08:59:30.770 に答える