轨道3和Rspec的:计数器缓存列时预计1被更新为2 [英] Rails 3 and Rspec: counter cache column being updated to 2 when expected 1

查看:120
本文介绍了轨道3和Rspec的:计数器缓存列时预计1被更新为2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我测试使用RSpec一个型号命名的解决方案,有很多喜欢。解决方案店有多少喜欢它有(counter_cache)。它有一个likes_count属性(以及相应的数据库字段)。

当我创建关联到一个解决方案一个类似的纪录,我期望的解决方案属性likes_count应该从零到1被更新。当我这样做,在控制台,它的工作原理。

但是当我运行规范,做同样的事情我做的控制台,它更新两次likes_count字段,将其设置为2。

看看(控制台)的工作

  IRB(主):001:0>解决方案=厂(:溶液)
IRB(主):004:0> solution.likes_count
=>零
IRB(主):006:0>像=厂(:喜欢,:可爱=>的解决方案)
=> #<喜欢的ID:1,USER_ID:2,likeable_id:1,likeable_type:解决方案,
   created_at:2011-11-23 19点31分23秒,的updated_at:2011-11-23 19点31分23秒>
IRB(主):007:0> solution.reload.likes_count
=> 1
 

看看规格结果不工作

  1)时创建一个类似的解决方案计数器缓存应该增加
 故障/错误:subject.reload.likes_count.should为1

   预计#< Fixnum对象:3> => 1
        得了#&所述;长整数:5是氢。 => 2

   使用相同?,其中比较对象标识相比,
   但预期与实际是不一样的物件。使用
   actual.should ==预期,如果你不关心
   在本实施例的对象的身份。
 #./spec/models/solution_spec.rb:45:in`块(3级)与<顶(必填)>
 

下面是规范:

 说明反缓存吗
  让(:溶液){厂(:溶液)}

  它创建像时,应增加吗
    工厂(:喜欢,:可爱=>的解决方案)
    solution.reload.likes_count.should为1
  结束
结束
 

我看了看test.log中,我意识到,更新该计数器缓存列的数据库查询被称为在测试两次。

  SQL(0.5毫秒)INSERT INTO喜欢(created_at,likeable_id,likeable_type,的updated_at,USER_ID)VALUES(?,?,? ??,,)[created_at,星期三,2011年11月23日19时38分31秒UTC +00:00],[likeable_id,121],[likeable_type,解决方案],[的updated_at ,周三,2011年11月23日19时38分31秒UTC +00:00],[user_ID的,204]
  SQL(0.3ms)更新的解决方案SETlikes_count= COALESCE(likes_count,0)+ 1式解决方案,IDIN(SELECT解决方案,ID从解决方案WHERE解决方案 ID= 121 ORDER BY ID DESC)
  SQL(0.1毫秒)更新的解决方案SETlikes_count= COALESCE(likes_count,0)+ 1式解决方案,IDIN(SELECT解决方案,ID从解决方案WHERE解决方案 ID= 121 ORDER BY ID DESC)
  解决方法负载(0.3ms)选择解决方案。* FROM解决方案WHERE解决方案。ID=? LIMIT 1 [身份证,121]
 

解决方案

我有同样的问题。原来,我的 spec_helper.rb 被装载模式,第二次,因此创建第二个回调更新计数器。请确保您的解决方案模型没有被重新加载另一个进程。

以上答案也是正确的:你需要使用 == 而不是做比较,但是这不会解决你看到你的日志文件中多次更新。

I'm testing with Rspec a model named Solutions which has many Likes. Solution stores how many Likes it have (counter_cache). It has a "likes_count" attribute (and respective db field).

When I create a Like record associated to a Solution, I expect that the solution attribute "likes_count" should be updated from nil to 1. When I do that in console, it works.

But when I run the spec, doing the SAME THING I do in console, it update TWICE the "likes_count" field, setting it to 2.

Take a look (in console) WORKING:

irb(main):001:0> solution = Factory(:solution)
irb(main):004:0> solution.likes_count 
=> nil
irb(main):006:0> like = Factory(:like, :likeable => solution)
=> #<Like id: 1, user_id: 2, likeable_id: 1, likeable_type: "Solution", 
   created_at: "2011-11-23 19:31:23", updated_at: "2011-11-23 19:31:23">
irb(main):007:0> solution.reload.likes_count
=> 1

Take a look at the spec result NOT WORKING:

 1) Solution counter cache should be increased when a like is created
 Failure/Error: subject.reload.likes_count.should be 1

   expected #<Fixnum:3> => 1
        got #<Fixnum:5> => 2

   Compared using equal?, which compares object identity,
   but expected and actual are not the same object. Use
   'actual.should == expected' if you don't care about
   object identity in this example.
 # ./spec/models/solution_spec.rb:45:in `block (3 levels) in <top (required)>'

Here is the spec:

describe "counter cache" do
  let(:solution) { Factory(:solution) }

  it "should be increased when a like is created" do
    Factory(:like, :likeable => solution)
    solution.reload.likes_count.should be 1
  end
end  

I took a look at test.log and I realized that the db query that updates the counter cache column was called two times in the test.

  SQL (0.5ms)  INSERT INTO "likes" ("created_at", "likeable_id", "likeable_type", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?)  [["created_at", Wed, 23 Nov 2011 19:38:31 UTC +00:00], ["likeable_id", 121], ["likeable_type", "Solution"], ["updated_at", Wed, 23 Nov 2011 19:38:31 UTC +00:00], ["user_id", 204]]
  SQL (0.3ms)  UPDATE "solutions" SET "likes_count" = COALESCE("likes_count", 0) + 1 WHERE "solutions"."id" IN (SELECT "solutions"."id" FROM "solutions" WHERE "solutions"."id" = 121 ORDER BY id DESC)
  SQL (0.1ms)  UPDATE "solutions" SET "likes_count" = COALESCE("likes_count", 0) + 1 WHERE "solutions"."id" IN (SELECT "solutions"."id" FROM "solutions" WHERE "solutions"."id" = 121 ORDER BY id DESC)
  Solution Load (0.3ms)  SELECT "solutions".* FROM "solutions" WHERE "solutions"."id" = ? LIMIT 1  [["id", 121]]

解决方案

I had the same problem. It turned out that my spec_helper.rb was loading the models a second time and therefore creating a second callback to update the counters. Make sure your Solution model isn't being reloaded by another process.

The answer above is also correct: you need to use == instead of be to do the comparison, but that will not fix the multiple updates that you are seeing in your log file.

这篇关于轨道3和Rspec的:计数器缓存列时预计1被更新为2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆