有没有办法防止rails中的序列化属性更新,即使没有更改?

Tab*_*rez 10 serialization ruby-on-rails update-attributes ruby-on-rails-3

这可能是所有新用户迟早会发现有关Rails的事情之一.我刚刚意识到rails正在使用serialize关键字更新所有字段,而不检查内部是否真的发生了任何变化.在某种程度上,这是通用框架的明智之举.

但有没有办法覆盖这种行为?如果我可以跟踪序列化字段中的值是否已更改,是否有办法阻止它在更新语句中被推送?我尝试使用"update_attributes"并将哈希值限制在感兴趣的字段中,但rails仍然更新所有序列化字段.

建议?

Jor*_*ris 1

是的,这也困扰着我。这是我对 Rails 2.3.14(或更低版本)所做的:

# config/initializers/nopupdateserialize.rb

module ActiveRecord
  class Base
    class_attribute :no_serialize_update
    self.no_serialize_update = false
  end
end

module ActiveRecord2
  module Dirty

    def self.included(receiver)
      receiver.alias_method_chain :update, :dirty2
    end

    private 

    def update_with_dirty2
      if partial_updates?
        if self.no_serialize_update
          update_without_dirty(changed)
        else
          update_without_dirty(changed | (attributes.keys & self.class.serialized_attributes.keys))
        end
      else
        update_without_dirty
      end
    end

  end
end

ActiveRecord::Base.send :include, ActiveRecord2::Dirty
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器中使用:

model_item.no_serialize_update = true
model_item.update_attributes(params[:model_item])
model_item.increment!(:hits)
model_item.update_attribute(:nonserializedfield => "update me")

etc.
Run Code Online (Sandbox Code Playgroud)

或者,如果您不希望创建序列化字段后对其进行任何更改,则在模型中定义它(但 update_attribute(:serialized_field => "update me" 仍然有效!)

class Model < ActiveRecord::Base
  serialize :serialized_field

  def no_serialize_update
    true
  end

end
Run Code Online (Sandbox Code Playgroud)