Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何拯救模型事务并向用户显示错误?_Ruby On Rails_Ruby_Activerecord_Transactions - Fatal编程技术网

Ruby on rails 如何拯救模型事务并向用户显示错误?

Ruby on rails 如何拯救模型事务并向用户显示错误?,ruby-on-rails,ruby,activerecord,transactions,Ruby On Rails,Ruby,Activerecord,Transactions,假设你有两个模型,Person和Address,每个人只有一个地址可以标记为Main。因此,如果我想更改一个人的主地址,我需要使用一个事务,将新地址标记为主地址,并取消旧地址的标记。据我所知,在控制器中使用事务并不好,所以我在模型中有一个特殊的方法,这就是我得到的: AddressesController < ApplicationController def update @new_address = Address.find(params[:id]) @old_address

假设你有两个模型,Person和Address,每个人只有一个地址可以标记为Main。因此,如果我想更改一个人的主地址,我需要使用一个事务,将新地址标记为主地址,并取消旧地址的标记。据我所知,在控制器中使用事务并不好,所以我在模型中有一个特殊的方法,这就是我得到的:

AddressesController < ApplicationController
 def update
  @new_address = Address.find(params[:id])
  @old_address = Address.find(params[:id2])
  @new_address.exchange_status_with(@old_address)       
 end
end
地址控制器
型号:

class Address < ActiveRecord::Base
  def exchange_status_with(address)
    ActiveRecord::Base.transaction do
     self.save!
     address.save!
    end     
  end
end
类地址
所以问题是,如果model方法中的事务失败,我需要拯救它并通知用户错误,我该如何做?是否有一种方法可以使此模型方法返回true或false,这取决于事务是否成功,就像save方法一样

我可能可以将该事务放在控制器中,并在rescue部分呈现错误消息,但我猜这是不对的,或者我可以将该方法放在回调中,但想象一下,有什么原因我不能这样做,还有什么其他选择

PS不要注意查找带有params id和id2的实例,只是随机地显示我有2个实例

def exchange_status_with(address)
  ActiveRecord::Base.transaction do
   self.save!
   address.save!
  end
rescue ActiveRecord::RecordInvalid => exception
  # do something with exception here
end
仅供参考,例外情况如下所示:

#<ActiveRecord::RecordInvalid: Validation failed: Email can't be blank>
旁注,您可以更改
self.save
保存


如果要保留活动模型错误,请选择其他解决方案:

class MyCustomErrorClass < StandardError; end

def exchange_status_with(address)
  ActiveRecord::Base.transaction do
   raise MyCustomErrorClass unless self.save
   raise MyCustomErrorClass unless address.save
  end
rescue MyCustomErrorClass
  # here you have to check self.errors OR address.errors
end
类MyCustomErrorClass
您可以在
rescue
中指示失败的交易,之后可以在控制器中检查错误,谢谢兄弟,我得到了完美的答案。如果有人感兴趣,我已经创建了TIL注释,总结了基于此SO问题的拯救交易的不同做法和不做法
class MyCustomErrorClass < StandardError; end

def exchange_status_with(address)
  ActiveRecord::Base.transaction do
   raise MyCustomErrorClass unless self.save
   raise MyCustomErrorClass unless address.save
  end
rescue MyCustomErrorClass
  # here you have to check self.errors OR address.errors
end