#new_record?函数确定是否已保存记录。但这始终是错误的after_save
。有没有办法确定记录是新创建的记录还是更新的旧记录?
我希望不要使用另一个回调,例如before_create
在模型中设置标志或要求对数据库进行另一个查询。
任何建议表示赞赏。
编辑:需要在after_save
钩子中确定它,对于我的特定用例,没有updated_at
或updated_on
时间戳
#new_record?函数确定是否已保存记录。但这始终是错误的after_save
。有没有办法确定记录是新创建的记录还是更新的旧记录?
我希望不要使用另一个回调,例如before_create
在模型中设置标志或要求对数据库进行另一个查询。
任何建议表示赞赏。
编辑:需要在after_save
钩子中确定它,对于我的特定用例,没有updated_at
或updated_on
时间戳
我正在寻找将其用于after_save
回调。
一个更简单的解决方案是使用id_changed?
(因为它不会在 上更改update
)或者即使created_at_changed?
存在时间戳列。
更新:正如@mitsy 指出的那样,如果在回调之外需要此检查,则使用id_previously_changed?
. 请参阅文档。
我知道这里没有轨道魔法,你必须自己做。您可以使用虚拟属性来清理它...
在您的模型类中:
def before_save
@was_a_new_record = new_record?
return true
end
def after_save
if @was_a_new_record
...
end
end
对于那些确实有updated_at
时间戳的人来说,还有另一种选择:
if created_at == updated_at
# it's a newly created record
end
有一个after_create
回调,只有在记录是新记录时才会调用,在它被保存之后。after_update
如果这是已更改并保存的现有记录,则还有一个回调供使用。after_save
回调在这两种情况下都会被调用,或者在或者after_create
被after_update
调用之后。
after_create
如果您需要在保存新记录后发生某事,请使用此选项。
更多信息在这里:http ://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
由于对象已经保存,您需要查看以前的更改。ID 只应在创建后更改。
# true if this is a new record
@object.previous_changes[:id].any?
还有一个实例变量@new_record_before_save
。您可以通过执行以下操作来访问它:
# true if this is a new record
@object.instance_variable_get(:@new_record_before_save)
两者都很丑陋,但它们可以让您知道对象是否是新创建的。希望有帮助!
Rails 5.1+方式:
user = User.new
user.save!
user.saved_change_to_attribute?(:id) # => true
对于 Rails 4(在 4.2.11.1 上检查)changes
和previous_changes
方法的结果是{}
内部对象创建的空哈希after_save
。所以attribute_changed?
像这样的方法id_changed?
不会按预期工作。
但是您可以利用这些知识 - 知道至少 1 个属性必须在changes
更新时 - 检查是否changes
为空。一旦你确认它是空的,你必须在对象创建期间:
after_save do
if changes.empty?
# code appropriate for object creation goes here ...
end
end
有一种方法previously_new_record?
正是针对这个用例而调用的。
user = User.new
user.new_record? # => true
user.previously_new_record? # => false
user.save
user.new_record? # => false
user.previously_new_record? # => true
看起来通过调用提出的解决方法saved_change_to_id?
不再起作用。我在 Rails 7 上。