运行Rails Posols在开发中,Activeresource增加了额外的类



我们有2个模型:估值和文档。两者都在微服务中,因此我们使用ActiverSource访问它们。

class Valuation < ActiveResource::Base
  self.site = "#{config.valuation_service.base_url}/valuations"
  self.include_root_in_json = false
end
class Document < ActiveResource::Base
  self.site = "#{config.valuation_service.base_url}/documents"
  self.include_root_in_json = true
end

在开发中运行导轨控制台。

>> Valuation.new(documents: [{ title: 'Foo' }])
=> <Valuation:0x007f9af85f1708 @attributes={"documents"=>[#<Valuation::Document:0x007f9af85f0970 @attributes={"title"=>"Foo"}, @prefix_options={}, @persisted=false>]}, @prefix_options={}, @persisted=false>

因此,文档的类名是Valuation:Document。当您在生产中运行Rails控制台时

>> Valuation.new(documents: [{ title: 'Foo' }])
=> <Valuation:0x007f9af595b478 @attributes={"documents"=>[#<Document:0x007f9af595a500 @attributes={"title"=>"Foo"}, @prefix_options={}, @persisted=false>]}, @prefix_options={}, @persisted=false>

文档的类仅Document,它尊重confient,例如 include_root_in_json

更大的问题是在对象上调用.to_json时。

# development
>> Valuation.new(documents: [{ title: 'Foo' }]).to_json
=> "{"documents":[{"title":"Foo"}]}"
# production
>> Valuation.new(documents: [{ title: 'Foo' }]).to_json
=> "{"documents":[{"document":{"title":"Foo"}}]}"

我们使用的是Rails 4.2.10。

到底是什么原因引起的?我已经检查了配置是否有任何因环境打开/关闭的东西,但找不到任何东西。

activeresource似乎正在使用自动加载机制,以动态地将属性名称转换为集合的类。

因此,开发和生产之间的差异是由于急切的负载。在生产中,所有文件都急切地加载,因此运行控制台时所有常数都存在。

在开发模式下运行控制台时,ActiverEsource试图定义属性的类名称,但是该机制对您的用例不起作用。

如果在Object上找不到常数,则在开始的类中创建它(Valuation(。

为了使开发与生产相同,您需要绕过触发这种自动加载机制。可以使用Rails的require_dependency方法轻松完成。

只是添加

require_dependency 'document'
class Valuation < ActiveResource::Base

Valuation类之前,一切都应该很好。

此行确保在任何人尝试创建Valuation类的实例之前已经加载了Document常数,并且自动加载机制不会使用。