【问题标题】:How can this code throw a ActiveRecord::ReadOnlyRecord exception?此代码如何引发 ActiveRecord::ReadOnlyRecord 异常?
【发布时间】:2011-11-11 16:30:22
【问题描述】:

我有一个has_one 优惠券购买模型。

购买模型包含以下代码:

def decrement_coupon
  coupon = Coupon.find_by_code(coupon_code, :readonly => false)
  return unless coupon.respond_to?(:uses)
  coupon.uses = coupon.uses - 1
  coupon.save
end

但是前几天我收到了这个错误:

ActiveRecord::ReadOnlyRecord - ActiveRecord::ReadOnlyRecord:
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/persistence.rb:245:in `create_or_update'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/callbacks.rb:273:in `create_or_update'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activesupport-3.0.6/lib/active_support/callbacks.rb:419:in `_run_save_callbacks'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/callbacks.rb:273:in `create_or_update'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/persistence.rb:39:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/validations.rb:43:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/attribute_methods/dirty.rb:21:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:240:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:292:in `with_transaction_returning_status'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:207:in `transaction'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:290:in `with_transaction_returning_status'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:240:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:251:in `rollback_active_record_state!'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/transactions.rb:239:in `save'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/associations/association_proxy.rb:222:in `send'
 /usr/local/rvm/gems/ree-1.8.7-2010.02@lyconic/gems/activerecord-3.0.6/lib/active_record/associations/association_proxy.rb:222:in `method_missing'
 /var/www/88tactical_production/releases/20110823232510/app/models/purchase.rb:69:in `decrement_coupon'

:readonly => false 不保证非只读记录吗?将此功能移至 Coupon 模型会有所不同吗? (我可能会这样做)

【问题讨论】:

  • 不是答案,但您尝试过Coupon.readonly(false).find_by_code(code) 吗?我不记得看到 :readonly 选项正式弃用,但我相信使用类似范围的 Model.readonly 方法是“Rails 3 Way”
  • @numbers1311407 在我的测试中,两者之间没有区别,我认为我没有收到弃用警告。

标签: ruby-on-rails ruby-on-rails-3 activerecord readonly


【解决方案1】:

这可能是由于通过 find_by_code() 助手加入了其他子值。

当 ActiveRecord 使用连接来查找返回附加值的对象时,它会将记录标记为只读。

这里有关于这个问题的详细描述:

What is causing this ActiveRecord::ReadOnlyRecord error?

如果是这种情况,您可能可以通过将您的 :joins 转换为适当的 :include 来解决此问题,以填充 ActiveRecord 实例而不将它们标记为已读-仅限。

【讨论】:

  • Coupon 的默认范围内确实有一个joins 调用。这里让我感到困惑的是,明确传递 :readonly => false 在控制台中有效,但无论如何我在生产中遇到了错误。
  • 这是一个操作顺序 - 你正在关闭 read_only,但是在处理 ActiveRecord 时(在采用默认的 false 值之后)它会将其设置为 true,因为你传递了一个 :joins。
猜你喜欢
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2018-11-30
相关资源
最近更新 更多