Lambda 在Rails4中测试命名作用域的最佳方法

Lambda 在Rails4中测试命名作用域的最佳方法,lambda,ruby-on-rails-4,rspec2,named-scope,proc,Lambda,Ruby On Rails 4,Rspec2,Named Scope,Proc,作为从Rails3.2迁移到Rails4的一部分,所有命名作用域都需要一个proc块。请在此处阅读更多信息: 我错过了更新我的一个模型中的一个作用域,这在我迁移后的生产中对我造成了伤害。所以我想弄清楚如何测试这个问题,我发现了一些奇怪的行为 在某些情况下,没有proc时作用域似乎可以正常工作,但在其他情况下则不行 # models/offer.rb class Offer < ActiveRecord::Base scope :roster, where(:on_roster =&g

作为从Rails3.2迁移到Rails4的一部分,所有命名作用域都需要一个proc块。请在此处阅读更多信息:

我错过了更新我的一个模型中的一个作用域,这在我迁移后的生产中对我造成了伤害。所以我想弄清楚如何测试这个问题,我发现了一些奇怪的行为

在某些情况下,没有proc时作用域似乎可以正常工作,但在其他情况下则不行

# models/offer.rb
class Offer < ActiveRecord::Base

  scope :roster, where(:on_roster => true)
  scope :commit, where("status_id > 5")

end
但是,如果我在rails控制台中将两个作用域调用链接在一起,则每个查询中只包含来自链中最后一个作用域的约束:

2.0.0-p247 :003 > Offer.roster.commit.all.size
  Offer Load (1.4ms)  SELECT "offers".* FROM "offers" WHERE (status_id > 5)
 => 3
2.0.0-p247 :004 > Offer.commit.roster.all.size
  Offer Load (0.7ms)  SELECT "offers".* FROM "offers" WHERE "offers"."on_roster" = 't'
 => 1 
现在,如果我编辑我的模型,将proc添加到第二个命名范围,如下所示:

class Offer < ActiveRecord::Base

  scope :roster, where(:on_roster => true)
  scope :commit, -> { where("status_id > 5") }

end
# models/offer.rb
class Offer < ActiveRecord::Base

  scope :roster, -> { where(:on_roster => true) }
  scope :commit, -> { where("status_id > 5") }

end
因此,第一个结果是正确的,并加载两个作用域,但第二个结果是错误的,只加载最后一个作用域。然后,如果将两个作用域都更改为使用procs,如下所示:

class Offer < ActiveRecord::Base

  scope :roster, where(:on_roster => true)
  scope :commit, -> { where("status_id > 5") }

end
# models/offer.rb
class Offer < ActiveRecord::Base

  scope :roster, -> { where(:on_roster => true) }
  scope :commit, -> { where("status_id > 5") }

end
请注意,调用
重新加载将不会更新作用域的行为。您必须结束rails控制台会话并开始一个新的会话,以使proc与non-proc正确地进行比较

我的问题是如何测试以确保我的所有作用域都按预期运行?每次我想测试它们是否有proc或lambda块时,将作用域链接在一起似乎非常混乱。然而,我在示波器上设置的简单测试告诉我,我所有的示波器都通过了,并且给出了假阳性结果


有没有一种简单的方法可以通过Rspec和Rails4测试指定的作用域是驻留在proc块中还是驻留在lambda块中

作用域只是定义类方法的语法糖,因此通过查看代码,很难知道您的作用域是否是proc/lambda

我能想到的唯一解决方案是使用RR和代理scope方法。这样,若主体不响应调用,您可以引发异常。在您的测试中,您希望不会出现异常。但我怀疑这是否会起作用,因为一旦设置了代理,类就已经被加载,因此,scope方法已经被调用

我想与其通过测试强制使用Proc,不如覆盖
scope
方法,根本不允许非Proc/-lambda

供参考:

答案很简单-始终在您的作用域中使用proc对象。^您的答案完全没有抓住要点。问题是如何通过测试确保所有作用域都有proc。我正在寻找一种解决方案,允许设置适当的TDD,使其从红色变为绿色。然后,您应该粘贴通过的测试,而不是列出一个小秘密的完整故事。^粘贴的测试结果可能对某些人有所帮助,但我想大多数人会得出和我一样的结论。rails控制台语句和响应更清楚、更简洁地说明了导致误报的查询是如何构建的,而不是显示误报本身,因为误报本身对于这些测试返回误报的原因没有任何帮助,以及为什么其他潜在的测试也可能是错误的。我同意,通过对命名范围定义进行monkey修补来要求它,可以确保所有命名范围都定义了procs/lambda。我希望找到一种简单的方法来测试它,因为对于迁移到4.0的人来说还为时过早,我认为这样的测试对其他希望确保升级正确的人会有所帮助。
$ rails c
2.0.0-p247 :002 > Offer.roster.commit.all.size
  Offer Load (1.3ms)  SELECT "offers".* FROM "offers" WHERE "offers"."on_roster" = 't' AND (status_id > 5)
 => 0
2.0.0-p247 :001 > Offer.commit.roster.all.size
  Offer Load (1.7ms)  SELECT "offers".* FROM "offers" WHERE "offers"."on_roster" = 't' AND (status_id > 5)
 => 0