gpt4 book ai didi

ruby-on-rails - Rails Rspec allow_any_instance_of 为 ActiveRecord 对象属性引发 "does not implement"错误

转载 作者:行者123 更新时间:2023-12-04 06:27:51 24 4
gpt4 key购买 nike

我有下一个问题。当我尝试使用 stub ActiveRecord 模型的实例方法时allow_any_instance_of 我收到错误消息“模型未实现#method”,但是如果我在此 stub 之前向数据库发送真实请求以创建或选择此模型的实例对象,我没有此消息并且一切正常!
我在控制台中有同样的问题

Reloading...

>> Search.method_defined?(:tickets_count)
=> false

>> Search.method_defined?(:affiliate_id)
=> false

>> Search.last
Search Load (3.9ms) SELECT "searches".* FROM "searches" ORDER BY "searches"."id" DESC LIMIT 1
=> #<Search:0x007fe2aecf2900
id: 515711,
tickets_count: 1,
affiliate_id: nil

>> Search.method_defined?(:affiliate_id)
=> true

>> Search.method_defined?(:tickets_count)
=> true

谁能解释一下,到底发生了什么?))

最佳答案

您在这里遇到的是 activerecord 对数据库属性访问器方法的延迟实例化。

TL;DR 你可以使用这样的 https://github.com/rspec/rspec-rails/issues/1357

本质上,ActiveRecord::Base 类在需要之前不会定义任何基于数据库列的 setter/getter,通常是通过缺少方法的钩子(Hook),尽管可能存在其他可能导致它们被定义的事情,例如调用Search.find_by_affiliate_id也可能导致加载定义。

我可以提供关于它如何/为什么以这种方式工作的高级解释,但是可能有更好/更新的资源可以更好地解释它,或者您可以通读 ActiveRecord 源代码,虽然有点迟钝,可能是理解其行为的合理选择。

那么为什么没有定义这些方法呢?

当通过继承 ActiveRecord::Base 创建新的 ActiveRecord 类时,所有类都知道它是预期的表名,但在没有连接到数据库的情况下不知道也无法知道该表具有哪些列。在不知道存在哪些列的情况下,它无法知道要定义哪些读取器/写入器。 ActiveRecord 不会在加载时主动查询数据库,我认为这是一件非常好的事情,因为它允许您加载代码而无需迁移的连接数据库。

ActiveRecord 所做的是 Hook method_missing , responds_to?等,以确定何时在未定义的 ActiveRecord 类上调用方法,尝试加载当前的数据库模式并为它找到的每一列在其自身上定义读取器/写入器/访问器方法,然后重试方法调用以查看如果现在已定义。

在上面的示例中,它可能不是 .last定义属性的调用,而是 .inspect调用您的终端运行以打印 Search 的实例目的。

要对此进行测试,您可以重新运行上面的示例,但替换 Search.last(s = Search.last).nil? .如果你这样做,我敢打赌Search.method_defined?(:affiliate_id)仍然是错误的。

希望这能解释为什么这些方法一开始没有定义,但后来被定义了。这也是你不能使用alias_method :aliased_affiliate_id, :affiliate_id的原因,这会失败,因为没有方法 affiliat_id在加载时定义。

对于您正在尝试做的事情,您需要决定是否值得需要一个事件的数据库连接才能运行这些规范。

如果是这样,您可以触发您的 ActiveRecord 类来加载它们的表定义并在您的规范中定义它们的读取器/写入器属性,以便通过此操作。

这里有人遇到了与 rspec 相同的问题,使用猴子补丁解决方案加载 activerecord 类的定义:

https://github.com/rspec/rspec-rails/issues/1357

关于ruby-on-rails - Rails Rspec allow_any_instance_of 为 ActiveRecord 对象属性引发 "does not implement"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40535640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com