2011-10-20 11 views
4

名前と設定が簡単なユーザーモデルがあります。ユーザーARELのすべての保存後に、設定列の更新が実行されます。例:Ruby on Railsは毎回シリアライズされた属性を更新します

user = User.find_by_name('kevin') 
user.save 

(0.3ms) UPDATE "users" SET "updated_at" = '2011-10-20 19:58:06.363541', "settings" = '--- {}' WHERE "users"."id" = 1 

saveを呼び出すと、他のフィールドは更新されません。これは予想される動作ですか?なぜ更新を実行していますか?シリアライズされた内容が変更されていない場合、変更しないようにオフにすることはできますか?私は最低限のケースを作成するために使用するサンプルプロジェクトをアップロードしました:

http://cl.ly/0p0j3Z3Y0L1x1I1p3Z0g

+0

あなたは上記の最初の行の直後にそれを呼び出す場合は、 'user.changes'の出力がどのようなものです:

は、以下の(ルビー1.8.7)のirbセッションを考えてみましょうか?属性のクラスを指定するとどうなりますか? 'serialize:設定、ハッシュ'? –

+0

@Hordanがハッシュを指定することは役に立ちません。 'User.changes'は空のハッシュを返します。 –

答えて

8

これは正常な動作です。シリアライズされた属性内の変更を検出するのは非常に難しいため、保存ごとに更新されます。

ruby-1.8.7-p352 :001 > x = "--- \n:b: 2\n:a: 1\n" 
=> "--- \n:b: 2\n:a: 1\n" 
ruby-1.8.7-p352 :002 > y = "--- \n:a: 1\n:b: 2\n" 
=> "--- \n:a: 1\n:b: 2\n" 
ruby-1.8.7-p352 :003 > x == y 
=> false 
ruby-1.8.7-p352 :004 > YAML.load(x) == YAML.load(y) 
=> true 
+0

なぜですか?シリアル化された後、u.settings_wasとu.settingsの文字列比較ができませんでしたか? –

+0

..答えを更新しました。さらに、Dirtyモジュールは、属性が変更されたときに特定のメソッドを呼び出すようにActiveRecordが想定しているため、変更が通知されます。たとえば、その場でハッシュ値を変更するプロセスにフックするのは非常に難しいでしょう。 – moritz