Ruby:循环依赖自动加载

Ruby: Circular Dependancy autoloading

我正在尝试修补 foreman bug,他们不会在构建后禁用网络引导,并在您想要重建主机时将其重新打开。看起来我只需要在 "built" 方法中添加一些代码:

./app/controllers/unattended_controller.rb

def built
    logger.info "#{controller_name}: #{@host.name} is Built!"
    update_ip if Setting[:update_ip_from_built_request]
    head(@host.built ? :created : :conflict)
 end

和 "setBuild" 方法在:

./app/models/host/managed.rb

def setBuild
  self.build = true
  self.save
  errors.empty?
end

借用 foreman_bootdisk.rb and modify_vm_cdrom.rb 第 79 行的灵感, 我想出了一些类似的东西:

def setBuild
  load '/usr/share/foreman/app/models/compute_resources/foreman/model/vmware.rb'
  if ComputeResources::Foreman::Model::Vmware.available?
      vm_reconfig_hardware('instance_uuid' => params[:token], 'hardware_spec' => {'bootOptions'=>['network', 'disk']})
  end
  self.build = true
  self.save
  errors.empty?
end

问题是我得到了错误,

Oops, we're sorry but something went wrong Circular dependency detected while autoloading constant ComputeResources::Foreman::Model::Vmware

我已经阅读了一些这方面的资料,听说问题可能出在 rail 的自动加载上,但我尝试用 load 和 require 修复这个问题(我试图避免自动加载功能,我听到的是 deprecated), but despite having tried both, I continue to get this error and I am unsure why. What am i doing differently than the coders of foreman_bootdisk.rb to get this error that they aren't? Whey doesn't vmware.rb 好像要加载?

我认为你的问题是常量名不正确引起的。你试过这样的事情吗?

def setBuild
  if Foreman::Model::Vmware.available?
    vm_reconfig_hardware('instance_uuid' => params[:token], 'hardware_spec' => {'bootOptions'=>['network', 'disk']})
  end
  self.build = true
  self.save
  errors.empty?
end

在 Foreman 源代码中没有常量 ComputeResources(末尾有 s),但是当您尝试在 rails 控制台中使用它时它会起作用。这是因为 rails 自动加载是一种动态创建模块,因为存在名称为 compute_resources.

的目录
def setBuild
  vm_reconfig_hardware(
    'instance_uuid' => params[:token],
    'hardware_spec' => {'bootOptions'=>['network', 'disk']}
  ) if Fog::Compute.providers.include?(:vsphere)

  self.build = true
  self.save
  errors.empty?
end