我有一个存储零售店详情的模型。
在Outlet模型中,我有一个前置过滤器
after_save :is_outlet_verified
def is_outlet_verified
if self.latitude.present? && self.longitude.present?
self.update_attributes(:is_verified => true)
else
self.update_attributes(:is_verified => false)
end
end
如果对地理位置进行地理编码,我想将is_verified
字段设置为true
。但是当成功执行is_outlet_verified时,它会触发after_save回调,这会再次触发is_outlet_verified。
答案 0 :(得分:17)
理想情况下,您会在before_save
回调中执行此类操作,而不是after_save
- 只需设置is_verified
属性,然后让保存正常进行。
如果您确实需要这样做,可以使用update_column
代替update_attribute
,这将跳过所有回调。
需要注意的一点是 - 如果before_save
回调返回false,则保存将不会继续。
答案 1 :(得分:5)
.update_attributes
调用.save
方法,因此调用它after_save
会产生无限循环
我会这样做before_save
,如下:
before_save :is_outlet_verified
def is_outlet_verified
if self.latitude.present? && self.longitude.present?
self.is_verified = true
else
self.is_verified = false
end
end
答案 2 :(得分:2)
您可以使用after_create
代替after_save
来避免update_attributes
答案 3 :(得分:1)
我最近遇到了这个问题,我解决了使用它的问题:)
update_columns (属性)公开
直接通过发出UPDATE SQL
语句在数据库中更新属性,并将其设置在接收者中:
user.update_columns(last_request_at: Time.current)
这是更新属性的最快方法,因为它直接进入数据库,但要考虑到结果是完全跳过了常规更新过程。特别是:
Validations
已跳过。
Callbacks
已跳过。
updated_at/updated_on
未更新。
在对新对象进行调用时,或者当至少一个属性标记为只读时,此方法将引发an +ActiveRecord::ActiveRecordError+
。