Ruby on rails 如何回滚rails保存/事务?
在我的控制器中,我有一些代码,如Ruby on rails 如何回滚rails保存/事务?,ruby-on-rails,activerecord,rollback,Ruby On Rails,Activerecord,Rollback,在我的控制器中,我有一些代码,如 ... if user.save something = Something.where("thing = ?", thing) if !(something.nil?) render json: { something: something } else #I WOULD LIKE TO ROLLBACK THE user.save HERE end else render json: {
...
if user.save
something = Something.where("thing = ?", thing)
if !(something.nil?)
render json: { something: something }
else
#I WOULD LIKE TO ROLLBACK THE user.save HERE
end
else
render json: { error: user.errors.full_messages }, status: :bad_request
end
我试过了
raise ActiveRecord::Rollback, "Could not create new User, Something was not found."
render json: { error: "Could not create new User, Something was not found"}, status: :unprocessable_entity
代替上面的回滚注释区域,但这不起作用。user.save最终会通过。它向“rails s”吐出一些内容,但不会回滚上一个事务。您可以这样做:
something = Something.where(thing: thing)
if something && user.save
render json: { something: something }
else
render json: { error: user.errors.full_messages }, status: :bad_request
end
您需要将代码包装在事务中,回滚才能正常工作。以下是文档: 差不多
ActiveRecord::Base.transaction do
# the code from your question
end
关键是
user.save
调用(它修改数据库)和raise-ActiveRecord::Rollback
调用都需要在该块中。如果您想以您提到的相同方式使用事务,可以这样做
User.transaction do
if user.save
something = Something.where("thing = ?", thing)
if !(something.nil?)
render json: { something: something }
else
raise ActiveRecord::Rollback
end
else
render json: { error: user.errors.full_messages }, status: :bad_request
end
end
不确定在事务中包装响应是否有效,但您需要对此进行测试
附言:
这两条线
something = Something.where("thing = ?", thing)
if !(something.nil?)
只是相当于
if Something.exists?(thing: thing)
你必须做
某事。通过查找某事是否存在。实际上,你甚至可以将其简化为某事。存在?(thing:thing)和&user.save
我认为他可以将这部分检查转移到另一个方法中,并使用before\u save回调调用它。这将是一个更好的方法。@AbuShady,你不认为在另一个事务中结束save
没有任何意义,而在内部save
是使用事务实现的!我认为我们应该让他知道哪些是不好的做法,而不是让他按自己的方式去做这个事务由我控制,我可以选择什么时候回滚,什么时候不回滚,当您想要对一组查询进行分组并使其保持原子状态时使用它()对于他的条件,可能是第二个条件受第一次保存的影响,所以您不能一起测试它们,因此,如果第二个条件失败,您需要能够回滚。另一方面,我很清楚这种情况,rails正为此原因为您提供回调。您可以使用“保存后”或“保存前”回调执行此操作,它将按承诺回滚并撤消所有操作。:)这个条件很简单,或者至少没有提供太多的信息,如果第二个查询与第一个保存完全无关,您的答案会更好,但是如果它以某种方式链接,则您需要执行事务,特别是如果第一个保存创建了更多的保存,例如。然后以优雅的方式执行该操作将使用after\u save,如果我没有错,我只是在问,我总是从错误中学习这到底是什么东西,它与用户有任何关系吗?