我有这样的交易
def accept_transaction
Purchase.transaction do
save! #Validate and Save purchase
product.update_bought
user.charge!(product.price)
Investment.add_spent(user_id: user.id,
spent: product.price)
end
如果事务未完成,我想要完成的是向Errors
对象添加相应的错误消息。所以期望的方法看起来像
def accept_transaction
Purchase.transaction do
save! #Validate and Save purchase(adds validation errors by default)
add_out_of_stock_error unless product.update_bought
add_no_money_error unless user.charge!(product.price)
other_error unless Investment.add_spent(user_id: user.id,
spent: product.price)
end
def add_out_of_stock_error
errors[:base].add("Product not available")
end
def no_money_error
...
end
def other_error
...
end
现在我无法获得所需的结果,这些操作会在出现故障时引发ActiveRecord::Rollback
错误,并且不会触发错误方法。
答案 0 :(得分:0)
听起来您想使用save
而不是save!
save!
会引发异常
http://apidock.com/rails/ActiveRecord/Base/save!
save
返回false
http://apidock.com/rails/ActiveRecord/Base/save
所以你可以这样做:
unless save
# add errors
end
但请注意回滚事务。
答案 1 :(得分:0)
我提出的解决方案(也感谢@lcguida)。是一个有点简单的
def accept_transaction
Purchase.transaction do
save! #Validate and Save purchase(adds validation errors by default)
catch_out_of_stock_error { product.update_bought }
catch_no_money_error { user.charge!(product.price) }
catch_other_error { Investment.add_spent(user_id: user.id,
spent: product.price) }
end
def catch_out_of_stock_error &block
begin
yield
rescue ActiveRecord::Rollback => e
errors.add(:base,"Product not available")
raise e
end
end
def catch_no_money_error &block
...
end
def catch_other_error &block
...
end
我的想法是,对于每个错误,我都有一个单独的方法,在那里我传入可能导致错误的方法。然后我在一个孤立的环境中从ActiveRecord::Rollback
救出,追加错误并重新引发同样的错误。
如果有更容易/更好的事情,请发布另一个答案。