对于与postgres数组相关的属性,ActiveModel :: Dirty没有覆盖Array.push(或者我最近读过的任何其他的就地修改方法){{ 3}}完善的。例如,如果Apple模型具有Apple.seeds数组,您将在Rails控制台中看到以下内容。
johnny = Apple.new()
# => <Apple #blahblahblah>
johnny.seeds
# => [] (assuming [] default)
johnny.seeds << "Oblong"
# => ["Oblong"]
johnny.changed?
# => false
johnny.seeds = []
johnny.seeds += ["Oblong"]
# => ["Oblong"]
johnny.changed?
# => true
因此,您可以使用两种不同的方式更改数组属性,但Rails只识别使用setter的方法。我的问题是,是否有一种方法(不会破坏Array类)使得push在ActiveRecord对象的上下文中表现得像一个setter,因此johnny.seeds << (x)
将反映在{{1}中}?
(在我看来,这是为了防止未来的开发人员使用推送数组属性,无意中无法记录更改,因为他们没有意识到这种限制。)
答案 0 :(得分:1)
任何具有可变对象的列都存在问题,而不仅仅是Array对象。
seeder = Apple.first
seeder.name
=> "Johnny "
seeder.name << " Appleseed"
seeder.changed?
=> false
您最好为未来的开发人员留言,但除此之外您可以考虑更换changed?
方法
class Apple
alias_method 'old_changed?', 'changed?'
def changed?
return old_changed? if old_changed?
return (seeds.count > 0) if new_record?
return seeds != Apple.find(id).seeds
end
end
但是,请注意,仅仅因为changed?
返回true
,并不能保证在update_attributes
中更新未更改object_id的字段...您可能会发现它们是不。您可能需要聘请了解这些陷阱的合格铁路开发人员。