Rails 将两个不同的模型实例保存为单个事务



我正在为注册表单编写一个服务对象,该表单记录了用户和公司模型的数据(仅供参考,我完全拒绝使用nested_attributes)。

没有公司(belongs_to)的存在,用户就不能存在。

如果公司成功,用户保存不成功,如何回滚公司的创建?

我在下面复制了测试来证明这一点。

  context 'when both are valid?' do
    subject { -> { sign_up_object.save } }
    it { should change(Company, :count).by(1) }
    it { should change(sign_up_object, :company).to be_a Company }
    it { should change(User, :count).by(1) }
    it { should change(sign_up_object, :user).to be_a User }
  end
  context 'when COMPANY is invalid' do
    subject { -> { sign_up_object.save } }
    before { allow_any_instance_of(Company).to receive(:save!).and_return false }
    it { should change(User, :count).by(0) }
    it { should change(Company, :count).by(0) }
  end
  context 'when USER is invalid' do
    before { allow_any_instance_of(User).to receive(:save!).and_return false }
    subject { -> { sign_up_object.save } }
    it { should change(User, :count).by(0) }
    it { should change(Company, :count).by(0) }  ->>>> this one fails!!!
  end

我目前拥有的代码看起来像这样

class SignUp
  ......
  def save_resources
    ActiveRecord::Base.transaction do
      save_company
      save_user
    end
  end
  def save_company
    company = new_company
    self.company = company if company.save!
  end
  def save_user
    user = new_user
    self.user = user if user.save!
  end
end

我确定ActiveRecord::Base.transaction块实际上并没有做任何事情,因为我的测试显示用户规范是唯一失败的,因为公司数量增加了 1。

您可以在未创建用户时手动回滚事务:

举个例子:

class SignUp
  ......
  def save_resources
    ActiveRecord::Base.transaction do
      save_company
      save_user
      raise ActiveRecord::Rollback if self.user.nil?
    end
  end
  def save_company
    company = new_company
    self.company = company if company.save!
  end
  def save_user
   user = new_user
   self.user = user if user.save!
 end
end

如果用户保存不成功,你可以摧毁公司

def save_resources    
  company = save_company
  user = save_user
  company.destroy if user.nil?
end

相关内容

  • 没有找到相关文章

最新更新