在我的控制器中,我经常具有以下功能:
@account = Account.new(account_params)
if @account.save
if @account.guest?
...
else
AccountMailer.activation(@account).deliver_later
@account.update_column(:activation_sent_at, Time.zone.now)
flash[:success] = "We've sent you an email."
redirect_to root_path
end
end
发送电子邮件 并更新activation_sent_at
属性而不必两次保存记录的最佳方法是什么?在这里打电话给update_column
并不适合我,因为AFAIK会创建一个额外的SQL查询(如果我输入错了,请更正我)。
答案 0 :(得分:2)
您的代码很好。我不会更改。
例如,您可能会想这样做:
@account = Account.new(account_params)
@account.activation_sent_at = Time.zone.now unless @account.guest?
if @account.save
if @account.guest?
...
else
AccountMailer.activation(@account).deliver_later
flash[:success] = "We've sent you an email."
redirect_to root_path
end
end
除了这个小问题,@account.guest?
周围现在有重复的逻辑,如果AccountMailer.activation(@account).deliver_later
失败了会发生什么?(当我说“失败”时,我的意思是-例如-AccountMailer
已重命名,因此控制器返回500错误。)
在这种情况下,您最终会得到一堆account
条记录,这些记录具有activation_sent_at
但从未发送过电子邮件;并且您将没有容易的方法来区分它们。
因此,此代码保证无论如何都要运行两个数据库调用:一个创建记录,然后另一个确认发送了电子邮件。如果将代码重构为仅执行单个数据库调用,那么您将很容易受到以下任一影响:
activation_sent_at
标记用户。控制器应该进行两笔交易,而不是一笔。这就是为什么我说:不要更改它。