我发现自己处于this SO post author的位置,我需要在某些类中覆盖ActiveRecord create / accessor方法,这些方法由自定义模块扩展。我已经探测过这个:
module ClassMethods
@ar_methods = [ :create, :find_by, :find_or_create_by, :update, :where ]
@ar_methods.each do | ar_method |
define_method(ar_method) do | attributes |
process_attributes!(attributes)
super(attributes)
end
end
def process_attributes!(attributes)
# process some attributes ...
end
end
这样可以正常工作,这样如果Bar
类被此模块扩展,那么
Bar.create(raw_attributes)
使用适当处理的属性在数据库中创建记录。
但是,当我的Foo
班级has_many :bars
出现问题时,会出现问题
foo.bars.create(raw_bar_attributes)
使用原始的未处理属性创建属于foo的bar
。我总是可以诉诸
foo.bars << Bar.create(raw_bar_attributes)
哪个有效,但我想避免为不警惕的同事设置一个陷阱,如果我能帮忙的话。那么我怎么能覆盖这些方法呢? ActiveRecord的内部对我来说是不透明的,所以我不完全确定从哪里开始。
提前致谢。
(关于我的实际问题的进一步背景:说,为了具体起见,我有一个Person
类,但由于一些莫名其妙的原因,许多月前采用了{{1}的惯例。在将其保存到数据库之前,实际年龄加倍,因此在整个代码库中我们没有编写person
,而是
Person.create(name: name, age: age)
从DB读取后用相似的体操除以2。但是进一步假设这个问题导致多个对象崩溃,并且我们的生产数据库中受影响最大的表在磁盘上是几百GB,并且多个遗留服务使用此约定不断写入和读取此表,因此它是修复根本原因是非常不切实际的(而且我们根本不知道采用这个惯例的原因,所以如果我们试图修复它,那么我们会担心会出现意想不到的事情。)这就是为什么我想在可以在受影响的类中共享的模块中封装可怕性的原因。 )