如何确定after_save中的记录是刚刚创建还是更新
#new_record?函数确定记录是否已保存。但在 after_save
挂钩中它始终为 false。有没有办法判断该记录是新创建的记录还是更新后的旧记录?
我希望不要使用另一个回调(例如 before_create
)在模型中设置标志或需要对数据库进行另一个查询。
任何建议表示赞赏。
编辑:需要在 after_save
挂钩中确定它,对于我的特定用例,没有 updated_at
或 updated_on
时间戳
The #new_record? function determines if a record has been saved. But it is always false in the after_save
hook. Is there a way to determine whether the record is a newly created record or an old one from update?
I'm hoping not to use another callback such as before_create
to set a flag in the model or require another query into the db.
Any advice is appreciated.
Edit: Need to determine it in after_save
hook, and for my particular use case, there is no updated_at
or updated_on
timestamp
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我希望将其用于
after_save
回调。一个更简单的解决方案是使用
id_changed?
(因为它不会在update
上更改),甚至使用created_at_changed?
(如果存在时间戳列)。更新:正如 @mitsy 指出的,如果在回调之外需要进行此检查,则使用 id_previously_changed? 。请参阅文档。
I was looking to use this for an
after_save
callback.A simpler solution is to use
id_changed?
(since it won't change onupdate
) or evencreated_at_changed?
if timestamp columns are present.Update: As @mitsy points out, if this check is needed outside of callbacks then use
id_previously_changed?
. See docs.据我所知,这里没有 Rails 魔法,你必须自己做。您可以使用虚拟属性来清理它......
在您的模型类中:
No rails magic here that I know of, you'll have to do it yourself. You could clean this up using a virtual attribute...
In your model class:
对于那些确实有
updated_at
时间戳的人来说,还有另一种选择:Yet another option, for those who do have an
updated_at
timestamp:有一个
after_create
回调,仅当记录是新记录时才会调用,在保存后。如果这是已更改并保存的现有记录,则还可以使用after_update
回调。在调用after_create
或after_update
后,这两种情况都会调用after_save
回调。如果您需要在保存新记录后执行某些操作,请使用
after_create
。更多信息请参见:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
There is an
after_create
callback which is only called if the record is a new record, after it is saved. There is also anafter_update
callback for use if this was an existing record which was changed and saved. Theafter_save
callback is called in both cases, after eitherafter_create
orafter_update
is called.Use
after_create
if you need something to happen once after a new record has been saved.More info here: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
由于对象已经保存,您需要查看之前的更改。 ID 仅应在创建后更改。
还有一个实例变量
@new_record_before_save
。您可以通过执行以下操作来访问它:两者都非常丑陋,但它们可以让您知道该对象是否是新创建的。希望有帮助!
Since the object has already been saved, you would you need to look at the previous changes. The ID should only change after a create.
There is also an instance variable
@new_record_before_save
. You can access that by doing the following:Both are pretty ugly, but they would allow you to know whether the object has been newly created. Hope that helps!
有一个名为
previously_new_record?
的方法正是针对此用例。来源: https://api.rubyonrails .org/v6.1.4/classes/ActiveRecord/Persistence.html#method-i-previously_new_record-3F
看起来通过调用
saved_change_to_id?
提出的解决方法不再起作用。我在 Rails 7 上。There is a method called
previously_new_record?
for exactly this use case.Source: https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Persistence.html#method-i-previously_new_record-3F
Looks like the proposed workaround by calling
saved_change_to_id?
doesn't work anymore. I'm on Rails 7.Rails 5.1+ 方式:
Rails 5.1+ way:
对于 Rails 4(在 4.2.11.1 上检查),
changes
和previous_changes
方法的结果是after_save 内创建对象时的空哈希值
。因此,像{}
id_changed?
这样的attribute_changed?
方法将无法按预期工作。但是您可以利用这些知识,并且知道更新时至少有 1 个属性必须位于“changes”中 - 检查“changes”是否为空。一旦确认它是空的,您必须在对象创建期间:
For Rails 4 (checked on 4.2.11.1) results of
changes
andprevious_changes
methods are empty hashes{}
on object creation insideafter_save
. Soattribute_changed?
methods likeid_changed?
won't work as expected.But you can take advantage of this knowledge and - knowing that at least 1 attribute has to be in
changes
on update - check ifchanges
is empty. Once you confirm that it's empty, you must be during object creation: