在rails中实例化模块

时间:2012-11-02 03:19:35

标签: ruby-on-rails-3.2 salesforce

我正在使用第三方库(gem)来实例化同一个Class的两个版本。 gem的文档实例化了Class

client.sobject_module = My::Module
client.materialize("Contact") #=> My::Module::Contact 

我的代码就是这样做的。

client.sobject_module = MyModule
client.materialize("Contact")

模块本身是空的

module MyModule 
end

相同代码有两个版本,但是当我这样做时

MyModule::Contact.find("John")
例如,似乎联系人已被归入全局命名空间。这是一个从gem

调用的materialize方法
def materialize(classnames)
  classes = (classnames.is_a?(Array) ? classnames : [classnames]).collect do |clazz|
    original_classname = clazz
    clazz = original_classname[0,1].capitalize + original_classname[1..-1]
    unless const_defined_in_module(module_namespace, clazz)
      new_class = module_namespace.const_set(clazz,  Class.new(Databasedotcom::Sobject::Sobject))
      new_class.client = self
      new_class.materialize(original_classname)
      new_class
    else
      module_namespace.const_get(clazz)
    end
  end
  classes.length == 1 ? classes.first : classes
end
new_class上的

客户端似乎设置正确,但是当我这样做时

MyModule::Contact.client  

它返回与

相同的客户端
MyModule1::Contact.client 

我花了几天时间试图解决这个问题,任何指针都会有所帮助。我使用的宝石是this

3 个答案:

答案 0 :(得分:0)

我想在这个问题(一年之后)敲了几个小时后总结我在这个领域的所有研究。

不幸的是,这是databasedotcom gem中的一个突出错误。问题是,目前sfdc客户端是类变量而不是类实例变量,因此我们的物化对象在客户端之间共享!

问题6373会详细讨论。您可以从这里获得以下几个选项:

  1. 使用monkey patch
  2. 使用针对上述问题的提示请求
  3. 使用databasedotcom-isolate gem
  4. 丢弃databsedotcom并使用为处理多个sfdc组织而构建的新restforce gem
  5. 我现在正在使用猴子补丁,因为它是阻力最小的路径。

答案 1 :(得分:0)

我刚刚发布了一个围绕宝石的包装器,让你绕过这个问题。 它有点像:

Databasedotcom::Isolated.perform(options) do
  # Constants are materialized automatically
  contact = Contact.last  

  # Work with them as needed
  puts contact.inspect
end

# And everything get's cleaned up behind you.
defined? Contact # => nil

它目前处于早期阶段,但我希望它符合您的需求。 来源位于https://github.com/sagmor/databasedotcom-isolated

答案 2 :(得分:0)

这是由于databasedotcom gem中的bug。您可以通过在初始化程序文件中添加猴子补丁来解决此问题

# config/initializers/databasedotcom.rb
Databasedotcom::Sobject::Sobject.class_attribute :client