为什么ActiveRecord#first调用之间的睡眠会改变其行为?

时间:2014-12-10 11:03:09

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

我继承了一些使用Rails编写的ruby 1.8.7代码〜> 2.3.15它包含一个看起来像这样的测试:

class Wibble < ActiveRecord::Base
  # Wibbles have integer primary keys and string names
end

def test
  create_two_wibbles
  w1 = Wibble.first
  sleep 2 # This sleep is necessary to
  w2 = Wibble.first

  w1.name = "Name for w1"
  w2.name = "Name for w2"

  w1.save

  w3 = Wibble.first

  assert(!w3.update_attributes(w2.attributes))
end

睡眠线旁边的评论没有被切断,字面意思是This sleep is necessary to。没有那个睡眠,这个测试失败了 - 删除它会改变行为,不会让它跑得快2秒。我一直在我们的版本控制系统中挖掘文件的历史记录,而且消息没有信息。我也无法联系这个测试的原作者来弄清楚他们想要做什么。

根据我的理解,我们将相同的记录从数据库中拉出两次,以两种不同的方式进行编辑,保存第一种,并断言我们不能保存第二种。我怀疑这是一个测试,以确保我们的数据库正确锁定表,但肯定如果这是失败我们的Wibbles会很好,ActiveRecord将是错误的。办公室里没有人能够弄清楚为什么这个测试可能是必要的,睡眠声明可能会有什么不同。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这可能是由Active Record缓存和memoization导致第二次查找停止实际进入数据库并获取新数据引起的。

实际上,尝试打印每个wibble的object_id;它们可能是完全相同的记忆对象。如果是这种情况,那么测试有点合理。

您也可以在控制器操作中执行相同的测试,并查看来自Rails的详细SQL日志;我希望第二个查找调用告诉你它刚刚使用了缓存数据并且实际上没有运行任何SQL查询。