2012-11-09 10 views
9

モデルのhas_manyとhas_many:throughモデルの関係があります。例えば、私のUserクラスに私が持っている:レールの変更を検出するhas_many:throughの関係

にhas_many:を通じて言語、::これらは「User.changes」関数を使用して追加または削除されたとき、私は希望何profile_languages

を検出することができることですUser.language_ids =関数で呼び出されたときに変更された属性の配列を返します。

他に誰かがこれをやろうとしましたか、これを経験しましたか? http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

編集:ActiveModel上

情報は、機能変更要求として、ここで私がやっているものです。ユーザーの属性が割り当てられた後、それを保存する前に

、私は外部のログに行われたすべての変更をログに記録するためには、.CHANGESから返された値のすべてで探しています。私が合格したときに、しかし

は、だから私はu.name = "新しい名前を" 呼び出す場合

はその後戻っ{[ '古い名前'、 '新しい名前'] name}をu.changesユーザがそのような

u.language_ids = [4,5]

などの言語IDの束がそこに作成ProfileLanguageモデルの数であり、u.changesハッシュは空白のままにされます。

私は手動でハッシュのいくつかの並べ替えを作成しますProfileLanguageモデルのいくつかのコールバックを作成しようとしていますが、これは確かに最善の解決策である場合、私は疑問に思って。

+0

こんにちは、あなたの質問についてもう少し詳しくお聞かせください。おそらく私たちにあなたがセットアップしているものを見せて、私たちに何かがあることを示してください。 – Noz

+0

コールバックやオブザーバーを調べましたか? – Ari

+0

編集を追加しました。うまくいけばそれは明らかにすることができる –

答えて

10

私は今とつもりです私のやや汚いソリューションは、has_manyの関数にコールバックを追加することです:

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

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

+0

それは私のために働かない。 after_addとbefore_removeのコールバックは、大量の代入を実行したとき(opのようにlanguage_idsで実行された場合)には起動されないようです。私は何か間違っているのですか? – morgler

+0

これは動作しますが、これらのコールバックはオブジェクトを個別に削除するたびに呼び出されます。 –

0

私は同じ問題を抱えていました。モデルを更新するときに新しい関係が作成されたか削除されたかどうかを確認しようとしていました。

私はmodel.relationship.any? { |a| a.changed? }を使用してみましたが、これは唯一のalredy既存のオブジェクトの変更を検出し、それは関係の作成と削除に取り組んでいませんでし。私が作成または破棄されているすべてのレコードを取得することができましたmodel.select { |a| a.new_record? || e.marked_for_destruction? }.any?を使用してlink

:ソリューションの検索

は、私たちの問題を解決し、この非常に簡単な記事を見つけました。

これをa.changed?と組み合わせると、私の関係がすべて変化することがあります。

+0

'accepts_nested_attributes_for'で動作しますが、一般的には動作しません。 – maxhs

0

テキストベースの変更ログを実装しようとしていることは知っていますが、あなたが望むものを達成するための方法としてpaper_trail gemを通して完全なオブジェクトバージョン管理を検討することをおすすめします。それはthis functionality according to their READMEを提供しています。

PaperTrailは団体の3種類を復元することができます-Oneがいます、-多くを持っており、HAS-多くのスルーを。これを行うには、インストール時にrail_trace:install --with-associationsオプションを生成するか、手動でversion_associationsテーブルを作成する必要があります。 PaperTrailは、関連付けられたレコードが変更されたときに、関連のバージョンとモデルのバージョンを関連付ける追加情報をそのテーブルに格納します。

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

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

関連する問題