
unless User.exist?(...) begin user = User.new(...) # Set more attributes of user user.save! rescue ActiveRecord::RecordInvalID,ActiveRecord::RecordNotUnique => e # Check if that user was created in the meantime user = User.exists?(...) raise e if user.nil? endend
原因是,正如您可能猜到的那样,多个进程可能同时调用此方法来创建用户(如果它尚不存在),因此当第一个进入块并开始初始化新用户时,设置属性并最终调用save!,可能已经创建了用户.
在这种情况下,我想再次检查用户是否存在,如果它仍然没有,则只引发异常(=如果在此期间没有其他进程创建它).
问题是,定期从保存中引发ActiveRecord :: RecordInvalID异常!并没有从救援区获救.
有任何想法吗?
编辑:
好吧,这很奇怪.我肯定错过了什么.我根据Simone的提示重构了代码,看起来像这样:
unless User.find_by_email(...).present? # Here we kNow the user does not exist yet user = User.new(...) # Set more attributes of user unless user.save # User Could not be saved for some reason,maybe created by another request? raise StandardError,"Could not create user for order #{self.ID}." unless User.exists?(:email => ...) endend 现在我得到以下异常:
ActiveRecord::RecordNotUnique: MysqL::DupEntry: Duplicate entry 'foo@bar.com' for key 'index_users_on_email': INSERT INTO `users` ...
抛出“除非user.save”的行.
怎么可能? Rails认为可以创建用户,因为电子邮件是唯一的,但是MysqL唯一索引会阻止插入?这有多大可能?怎么可以避免呢?
另外,不要忘记在用户模型中添加valIDates_uniqueness_of验证.
验证并不总能防止重复数据(两个并发请求以相同的毫秒写入的可能性极小).
如果将valIDates_uniqueness_of与索引结合使用,则不需要所有代码.
unless User.exist?(...) begin user = User.new(...) # Set more attributes of user user.save! rescue ActiveRecord::RecordInvalID,ActiveRecord::RecordNotUnique => e # Check if that user was created in the meantime user = User.exists?(...) raise e if user.nil? endend
变
user = User.new(...)# Set more attributes of userif user.save # savedelse # user.errors will return # the List of errorsend总结
以上是内存溢出为你收集整理的ruby-on-rails – 未获救的ActiveRecord异常全部内容,希望文章能够帮你解决ruby-on-rails – 未获救的ActiveRecord异常所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)