我想覆盖store_accessor
的getter。可以找到这里。代码如下:
# File activerecord/lib/active_record/store.rb, line 74
def store_accessor(store_attribute, *keys)
keys = keys.flatten
_store_accessors_module.module_eval do
keys.each do |key|
define_method("#{key}=") do |value|
write_store_attribute(store_attribute, key, value)
end
define_method(key) do
read_store_attribute(store_attribute, key)
end
end
end
self.stored_attributes[store_attribute] ||= []
self.stored_attributes[store_attribute] |= keys
end
我实现了我想要实现的功能,但是如果我也要覆盖setter,有一个方法对我来说不太清楚,那就是write_store_attribute(...)
方法(found 这里)。
守则如下:
# File activerecord/lib/active_record/store.rb, line 108
def write_store_attribute(store_attribute, key, value)
attribute = initialize_store_attribute(store_attribute)
if value != attribute[key]
send :"#{store_attribute}_will_change!"
attribute[key] = value
end
end
我不明白的方法是"#{whatever_store_att}_will_change!"
。
如果我要覆盖setter,我将使用update_attributes
或update_column
。该方法是否使赋值attribute[key]=value
实际上修改了DB中的字段,使其等效于update_attributes
发布于 2014-05-30 07:37:26
这是activemodel的变更跟踪系统的一部分,active record用来知道它需要写什么到db (如果有的话)。
当您调用对记录的保存时,activerecord将为它认为已更改的所有属性创建一个更新查询(如果没有更改的属性,那么它就什么也不会做)。
activerecord为您生成的访问器会自动为您处理这个问题,但在某些情况下,告诉activerecord属性是脏的,需要更改(例如,如果您在适当的地方更新某个内容,则可以绕过通常的更改跟踪机制)。
这正是这里所发生的事情:当您为存储的属性设置一个键时- rails修改哈希(而不是分配一个新的哈希),因此需要调用_will_change!
来让更改跟踪知道,下一次调用保存时,底层属性将需要写入db。
https://stackoverflow.com/questions/23958170
复制