我知道before_create是在对象转换到数据库之前调用的,而after_create是在之后调用的。
只有当对象无法满足数据库常量(唯一键等)时,才会调用before_create和after_create。另外,我可以将来自after_create的所有逻辑都放在before_create中
我是不是遗漏了什么?
发布于 2014-04-09 13:06:43
为了理解这两个回调,首先你需要知道这两个回调是什么时候被调用的。下面是ActiveRecord回调的顺序:
(-)保存
(-)有效
(1) before_validation
(-)验证
(2) after_validation
(3) before_save
(4) before_create
(-)创建
(5) after_create
(6) after_save
(7) after_commit
您可以看到,before_create
是在after_validation
之后调用的,在简单的上下文中,这个回调是在您的ActiveRecord满足验证之后调用的。此before_create
通常用于在验证后设置一些额外的属性。
现在转到after_create
,您可以看到这是在将记录持久存储到DB之后创建的。人们通常使用它来做一些事情,比如发送通知,记录日志。
对于这个问题,你应该什么时候使用它?答案是‘你根本不应该使用它’。ActiveRecord回调是反模式的,经验丰富的Rails开发人员将其视为代码气味,您可以通过使用服务对象包装来实现所有这些。这里有一个简单的例子:
class Car < ActiveRecord::Base
before_create :set_mileage_to_zero
after_create :send_quality_report_to_qa_team
end
can be rewritten in
# app/services/car_creation.rb
class CarCreation
attr_reader :car
def initialize(params = {})
@car = Car.new(params)
@car.mileage = 0
end
def create_car
if car.save
send_report_to_qa_team
end
end
private
def send_report_to_qa_team
end
end
如果你有一个简单的应用程序,那么回调是可以的,但随着你的应用程序的增长,你将会挠头,不确定是什么设置了这个或那个属性,测试将非常困难。
再想一想,我仍然认为你应该广泛使用回调,体验一下重构它的痛苦,然后你就会学会避免它;)祝你好运
发布于 2014-04-09 12:49:55
在将对象保存到数据库之前,可以使用before_create
回调设置对象的属性。例如,为记录生成唯一标识符。将其放入after_create
中将需要另一个数据库调用。
发布于 2014-04-09 13:37:39
before_create:
在db中保存新对象之前将被调用。当此方法返回false时,它将通过回滚来阻止创建。
因此,当你需要做一些事情,比如在保存之前检查一些东西,这在验证中是不合适的,你可以在before_create中使用它们。
例如:在创建新的Worker
之前,需要向Master
请求权限。
before_create :notify_master
def notify_master
# notify_master via ipc and
# if response is true then return true and create this successfully
# else return false and rollback
end
另一个用途是,正如Trung Lê
建议的那样,您希望在保存之前格式化一些属性,如大写名称等。
after_create:
第一次将object保存到数据库后调用。当你不想中断创建,只记下创建的笔记或在创建后触发某些东西时,这是很有用的。
例如:在使用角色mod
创建新的user
之后,我们想要通知其他mods
after_create :notify_mod,:is_mod?
def notify_mod
# send notification to all other mods
end
编辑:以下评论的
问:将notify_mod
放在after_create
中而不是before_create
中有什么好处
答:有时在数据库中保存对象时,由于数据库端验证或其他问题,它可能会回滚。
现在,如果你在创建之前已经编写了notify_mod
,那么即使创建没有完成,它也会被处理。毫无疑问,它会回滚,但它会产生开销。所以这很耗时
如果您已将其放在after_create
中,则只有在成功创建记录后,notify_mod
才会执行。从而减少了发生回滚时的开销。
另一个原因是,通知必须在用户创建之后而不是之前发送,这是合乎逻辑的。
https://stackoverflow.com/questions/22952664
复制相似问题