Ruby on rails 使用find_或create的Rails事务

Ruby on rails 使用find_或create的Rails事务,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,在我的Rails 4应用程序中,我有一个表单,可以将数据提交到两种不同的模型booking.rb和guest.rb。每个模型都必须验证各自的数据,并且只有当这两个数据都有效时,脚本的其余部分才能继续 我相信交易是解决这个问题的方法,事实上,我在同一个应用程序中有另一个场景,我确实使用了交易 但是,在这种情况下,@guest实例是通过以下方式生成的: @guest = Guest.find_or_create_by(:email => params[:email]) 当然,如果记录不存在,

在我的Rails 4应用程序中,我有一个表单,可以将数据提交到两种不同的模型
booking.rb
guest.rb
。每个模型都必须验证各自的数据,并且只有当这两个数据都有效时,脚本的其余部分才能继续

我相信交易是解决这个问题的方法,事实上,我在同一个应用程序中有另一个场景,我确实使用了交易

但是,在这种情况下,@guest实例是通过以下方式生成的:

@guest = Guest.find_or_create_by(:email => params[:email])
当然,如果记录不存在,这一行实际上会创建记录。我的理解是,如果事务实际被创建,它将不会回滚?理想情况下,我需要的是:

@guest = Guest.find_or_new(:email => params[:email])
但我不认为这是Rails的一个选项

然后,如果出现验证错误,我可以继续执行事务并回滚:

begin
  @booking.transaction do
    @booking.save!
    @guest.save!
  end
  redirect_to somewhere
rescue
  render :new
end

我的问题我如何使用一个事务验证这两个模型,同时考虑
通过
查找或创建?

如果事务回滚,则事务中完成的所有操作都将恢复。(好吧,几乎每件事都有一些特定于供应商的陷阱)

这同样适用于
find\u或
,只要在事务期间调用。回滚后,创建的对象仍在内存中,但备份数据库行不再存在

因此,只要您的代码看起来像这样,您就应该是安全的:

Booking.transaction do
  @guest = Guest.find_or_create_by(:email => params[:email])

  @booking.save!
  @guest.save!
end

你使用哪个数据库?(SQLite,PostgreSQL,…)我不确定这是否必要,不是在引擎盖下查找并创建调用save吗?我认为@DrewVerlee这里的想法是通过执行save!(砰的一声!)它强制了扑救。使用“!”对我来说仍然不起作用。。。。。当我在一个坏事务的中间调用FiffyOrthCube时,我的FiffyOrthCube甚至被用“Save!”来回滚<代码>客户机!代码>调用不是必需的,但它在OP的示例中存在。我保存它只是为了可视化如何将原始代码转换为单个事务,而无需重写整个事务(注意:也可以使用
find\u或\u create\u by!