我们有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
常数,并且自动加载机制不会使用。