Hartl 教程第 13.1.3 章 User/Micropost 关联:为什么使用 create 而不是使用引发异常的 bang 创建?
Hartl Tutorial Chapter 13.1.3 User/Micropost associations: Why use create instead of create with a bang that raises exceptions?
在Michael Hartl's rails tutorial chapter 13.3.1中,我们创建了一个twitter风格的微博,如下所示:
Micropost.create
我的问题是为什么使用 Micropost.create
而不是 Micropost.create!
?
似乎您总是希望在出现问题时在活动记录中引发异常,以便您可以解决异常。
为什么要使用 Micropost.create
?他解释说,两者都是 table 的选项:
但他并没有真正解释为什么你会选择其中之一。那么,您为什么要选择一个而不是另一个?
如果 create
失败,您并非完全一无所知。
my_micropost = Micropost.create
if my_micropost.persisted?
puts "successfully saved"
else
puts "something went wrong"
end
它为您提供了一种处理失败情况的简单机制。例如,您可以参考 my_micropost.errors
以确定问题所在并进行相应处理。
而在不向最终用户公开异常的情况下从 create!
恢复意味着您需要从引发的异常中解救出来,这是一个更复杂的过程。
嗯,这取决于你在哪里使用这个方法。
何时使用create
如果是在你的controller中简单的创建,一般会使用create
来控制流程逻辑,举个例子:
if Micropost.create(micropost_params)
# handle success save, e.g.:
redirect_to :index
else
# handle failure in save, e.g.:
render :new
end
使用上面的代码,您可以 控制流程 而无需 使用异常 ,这就是您创建记录时想要的:处理错误你知道这很可能会发生而不会引发异常。
所以,我更愿意反过来问:如果你可以得到 false
并处理错误,为什么要使用 create!
并引发异常(并获得相关的开销) ?如果我需要更多代码来处理该异常,为什么要这样做?
虽然这是一个有效的用法 create
,但并不常见,因为 save
和 update
更有可能被使用(在大多数情况下,您将使用 new
然后保存 save
).
何时使用create!
如果您想在同一操作中更新多条记录(阅读transactions),那么create!
会更好;考虑以下示例:
ActiveRecord::Base.transaction do
user1.update!(balance: user1.balance + 100)
user2.update!(balance: user2.balance - 100)
transfer.create!(amount: 100, receiver: user1, sender: user2)
end
在这里,您在同一个事务中更新了 2 条记录并创建了 1 条记录,但是如果其中一条记录失败,您需要进行回滚以保持数据完整性。因此,如果您使用 create
,您将需要自己处理回滚以撤消事务;另一方面,使用 create!
会引发异常,自动触发回滚。
create!
的另一个好用处是 testing(如 Hartl 的教程)和 debugging,我发现它们更方便因为它们有助于更快地发现错误。
在Michael Hartl's rails tutorial chapter 13.3.1中,我们创建了一个twitter风格的微博,如下所示:
Micropost.create
我的问题是为什么使用 Micropost.create
而不是 Micropost.create!
?
似乎您总是希望在出现问题时在活动记录中引发异常,以便您可以解决异常。
为什么要使用 Micropost.create
?他解释说,两者都是 table 的选项:
但他并没有真正解释为什么你会选择其中之一。那么,您为什么要选择一个而不是另一个?
如果 create
失败,您并非完全一无所知。
my_micropost = Micropost.create
if my_micropost.persisted?
puts "successfully saved"
else
puts "something went wrong"
end
它为您提供了一种处理失败情况的简单机制。例如,您可以参考 my_micropost.errors
以确定问题所在并进行相应处理。
而在不向最终用户公开异常的情况下从 create!
恢复意味着您需要从引发的异常中解救出来,这是一个更复杂的过程。
嗯,这取决于你在哪里使用这个方法。
何时使用create
如果是在你的controller中简单的创建,一般会使用create
来控制流程逻辑,举个例子:
if Micropost.create(micropost_params)
# handle success save, e.g.:
redirect_to :index
else
# handle failure in save, e.g.:
render :new
end
使用上面的代码,您可以 控制流程 而无需 使用异常 ,这就是您创建记录时想要的:处理错误你知道这很可能会发生而不会引发异常。
所以,我更愿意反过来问:如果你可以得到 false
并处理错误,为什么要使用 create!
并引发异常(并获得相关的开销) ?如果我需要更多代码来处理该异常,为什么要这样做?
虽然这是一个有效的用法 create
,但并不常见,因为 save
和 update
更有可能被使用(在大多数情况下,您将使用 new
然后保存 save
).
何时使用create!
如果您想在同一操作中更新多条记录(阅读transactions),那么create!
会更好;考虑以下示例:
ActiveRecord::Base.transaction do
user1.update!(balance: user1.balance + 100)
user2.update!(balance: user2.balance - 100)
transfer.create!(amount: 100, receiver: user1, sender: user2)
end
在这里,您在同一个事务中更新了 2 条记录并创建了 1 条记录,但是如果其中一条记录失败,您需要进行回滚以保持数据完整性。因此,如果您使用 create
,您将需要自己处理回滚以撤消事务;另一方面,使用 create!
会引发异常,自动触发回滚。
create!
的另一个好用处是 testing(如 Hartl 的教程)和 debugging,我发现它们更方便因为它们有助于更快地发现错误。