新唱片?函数确定记录是否已被保存。但是在 after_save钩子上总是错误的。是否有一种方法可以确定该记录是新创建的还是更新后的旧记录?
after_save
我希望不要使用另一个回调函数(如 before_create)来设置模型中的标志,或者需要对数据库进行另一个查询。
before_create
任何建议都不胜感激。
编辑: 需要在 after_save钩子中确定它,对于我的特定用例,没有 updated_at或 updated_on时间戳
updated_at
updated_on
据我所知,这里没有栏杆魔法,你只能自己动手了。您可以使用虚拟属性来清除这些..。
在你的模型课上:
def before_save @was_a_new_record = new_record? return true end def after_save if @was_a_new_record ... end end
我想用这个来做 after_save的复试。
一个更简单的解决方案是使用 id_changed?(因为它在 update上不会改变) ,如果存在时间戳列,甚至使用 created_at_changed?。
id_changed?
update
created_at_changed?
更新: 正如@mitsy 指出的,如果在回调之外需要这个检查,那么使用 id_previously_changed?。
id_previously_changed?
有一个 after_create回调函数,只有当记录是新记录 在它被拯救之后时才会调用该函数。如果这是已更改和保存的现有记录,则还有一个 after_update回调。在这两种情况下,在调用 after_create或 after_update之后,都会调用 after_save回调函数。
after_create
after_update
如果在保存新记录后需要发生某些事情,请使用 after_create。
更多信息请点击: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
还有一个选择,对于那些 做有 updated_at时间戳的人来说:
if created_at == updated_at # it's a newly created record end
因为对象已经被保存,所以您需要查看以前的更改。ID 应该只在创建之后更改。
# true if this is a new record @object.previous_changes[:id].any?
还有一个实例变量 @new_record_before_save,你可以通过以下操作进行访问:
@new_record_before_save
# true if this is a new record @object.instance_variable_get(:@new_record_before_save)
Both are pretty ugly, but they would allow you to know whether the object has been newly created. Hope that helps!
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内创建对象时的结果是空散列 {}。所以像 id_changed?这样的 attribute_changed?方法不会像预期的那样工作。
changes
previous_changes
{}
attribute_changed?
但是您可以利用这些知识,并且-知道在更新时至少有1个属性必须在 changes中-检查 changes是否为空。一旦你确认它是空的,你必须在创建对象的过程中:
after_save do if changes.empty? # code appropriate for object creation goes here ... end end
There is a method called previously_new_record? for exactly this use case.
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
资料来源: https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Persistence.html#method-i-previously_new_record-3F
看起来通过调用 saved_change_to_id?提出的解决方案不再有效了。我在 Rails 7上。
saved_change_to_id?