ActiveRecord表现不如我所料

时间:2014-06-30 13:14:17

标签: mysql ruby-on-rails activerecord ruby-on-rails-4

Ruby 2.0 Windows 8.1 Rails 4.1 MySQL2 gem

为避免错误,我在创建新的付款记录之前使用以下代码检查现有付款:

    payment = {"organization_id" => organization_id,
               "date" => row[1],
               "amount" => row[2],
               "description" => row[3]}
    slug = "#{organization_id.to_s}_#{row[1].to_s}_#{row[2].to_s}_#{row[3]})

    organization_payment = OrganizationPayment.where(:slug => slug)[0]
    if !organization_payment
      new_organization_payment = OrganizationPayment.create(payment)
    end

每隔一段时间,我就会收到以下错误:

Mysql2::Error at /process_uploaded_payments_data
Duplicate entry 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' for key 'index_organization_payments_on_slug'

我的模型中也有以下内容:

validates_uniqueness_of :slug

是否有任何理由导致重复错误的条目不会被上面的代码捕获?有什么想法吗?

解决方案

我仍然不确定是什么导致了这个问题,但是我学到了验证唯一性并不真正有用的困难方法,如果你的模型中还有一个创建了slug的before_save调用。解决方法是异常处理程序:

    begin
      new_organization_payment = OrganizationPayment.create(payment)
    rescue ActiveRecord::RecordNotUnique
       next
    end

1 个答案:

答案 0 :(得分:0)

我不知道这是否是您的问题,但可能的原因可能是race condition - 当您的代码在某个流程中运行时,它可能会在if条件创建之后立即中断新记录。

对数据库中的列设置唯一约束是处理此问题的好方法。您可以捕获异常并以这种方式处理它。您也不必手动检查双重性,您可以使用活动记录验证;取出整个记录只是为了检查它是否存在不是最好的做法。更多信息:

http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of