1

我正在使用 Solidus 和 Ruby on Rails 来创建一个网上商店,并且我有多个用于该网上商店的模块。

因此,我使用以下代码将 me 控制器定义到名为“solidus_jwt_auth”的模块中:

module Spree
  module Api
    class MeController < Spree::Api::BaseController
      def index
        ...
      end

      def orders
        ...
      end

      def addresses
        ...
      end
    end
  end
end

我想在另一个名为“solidus_prescriptions”的模块中扩展它,所以我使用以下代码为此创建了一个装饰器me_decorator

if defined? Spree::Api::MeController.class
  Spree::Api::MeController.class_eval do
    def prescriptions
      ...
    end

    def create_prescription
      ...
    end

    private

    def prescription_params
      params.require(:prescription).permit(
          *Spree::CustomerPrescription.permitted_attributes
      )
    end
  end
end

为此,我在solidus_prescription 模块中编写了单元测试,并在webshop 中编写了集成测试。单元测试工作正常,但集成测试出现以下错误:

错误:MeEndpointsTest#test_me/prescriptions_post_endpoint_throws_an_error_when_wrong_params:AbstractController::ActionNotFound:找不到 Spree::Api::MeController test/integration/me_endpoints_test.rb:68:in 'block in' 的操作'create_prescription'

这意味着他找不到在另一个模块中定义的 MeController。我如何检查 MeController 是否已定义,因为下面的代码对我没有任何帮助:

if defined? Spree::Api::MeController.class
end
4

2 回答 2

1

这最终奏效了:

def class_defined?(klass)
  Object.const_get(klass)
rescue
  false
end

if class_defined? 'Spree::Api::MeController'
 ....
end
于 2017-08-01T11:40:53.493 回答
1

if defined?应该完全按照您希望它在理论上做的事情。问题是你正在检查if defined? Spree::Api::MeController.class. 你的#class班级是Class. 所以你真正得到的是if defined? Class永远是真的!

这个问题很可能不是条件失败,而是它永远不会被读取。Rails 延迟加载您编写的大部分代码,这意味着文件在执行中被调用之前不会被读取。

装饰器模块应该只包含你想要添加的方法,没有条件或使用class_eval. 然后在原件中class你可以包含它。

module Spree
  module Api
    class MeController < Spree::Api::BaseController
      include MeDecorator
    end
  end
end

如果出于任何原因您不确定MeDecorator是否会被定义,请不要使用defined?,因为defined? MeDecorator如果未定义并加载必要的文件,则实际上不会去寻找它。nil如果常量没有值,它将返回。只是rescue一个NameError

module Spree
  module Api
    class MeController < Spree::Api::BaseController
      begin
        include MeDecorator
      rescue NameError => e
        logger.error e
      end
    end
  end
end
于 2017-08-01T12:55:48.907 回答