Ruby on rails Rails 4在保存之前的更改后不起作用
我在一个模型上有一个after_save回调,我正在调用previous_changes,以查看属性(is_complete)是否已更改。即使属性发生更改,之前的_更改也会返回一个空哈希 以下是回调:Ruby on rails Rails 4在保存之前的更改后不起作用,ruby-on-rails,ruby-on-rails-4,activerecord,awesome-nested-set,Ruby On Rails,Ruby On Rails 4,Activerecord,Awesome Nested Set,我在一个模型上有一个after_save回调,我正在调用previous_changes,以查看属性(is_complete)是否已更改。即使属性发生更改,之前的_更改也会返回一个空哈希 以下是回调: after_save do |record| puts "********************" puts record.previous_changes.to_s puts record.is_complete puts "********************" end
after_save do |record|
puts "********************"
puts record.previous_changes.to_s
puts record.is_complete
puts "********************"
end
下面是我在日志中得到的信息:
********************
{}
true
********************
********************
{}
false
********************
如果is_complete的值从true更改为false,则它应位于前一个_changes哈希中。正在通过正常保存完成更新!我不会重新加载对象
---更新---
我在发布问题时没有考虑到这一点,但我的模型使用了awesome_nested_set gem,这似乎是在重新加载对象或以某种方式干扰after_save回调。当我注释掉acts_as_nested_set时,回调似乎工作正常
---更新2---
使用around_save回调修复了这一问题,该回调首先确定属性是否已更改,然后生成,然后在数据库中进行更改后执行我需要它执行的操作。工作解决方案如下所示:
around_save do |record, block|
is_complete_changed = true if record.is_complete_changed?
block.call
if is_complete_changed
** do stuff **
end
end
我没有深入挖掘,但从第一眼看到你,在方法
之前的更改中
:
def previous_changes
@previously_changed ||= ActiveSupport::HashWithIndifferentAccess.new
end
@previous\u changed
没有在任何地方定义(,它使用我下面提到的changes
方法),因此您一直都会得到空的散列(虽然访问权限很好,但是:D)
您真正想要使用的是一种方法:
它将返回您预期的结果
#=> {"is_complete"=>[true, false]}
根据源代码
来自第274行
def changes_applied # :doc:
@previously_changed = changes
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
end
因此,在调用changes\u applicated
后,更改将设置为@先前更改的
,在调用save
时调用changes\u apply
,这意味着在执行持久性工作后(第42行)
总之,previous\u changes
仅在记录实际保存到持久存储(DB)时才有值
因此,在您的回调中,您可以使用record.changed\u attributes
,而在外部使用先前更改的
,它将正常工作 显然,可怕的嵌套集gem正在干扰回调;大概是在调用回调之前重新加载对象(参见上面的更新)。不确定是否有办法解决这个问题。谢谢你的帮助-johnpermant链接到更改
方法:已知错误-
def changes_applied # :doc:
@previously_changed = changes
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
end