我正在使用Solidus和Ruby on Rails创建一个网上商店,我为该网店提供了多个模块。
所以,我将一个控制器定义为一个名为'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模块和网上商店的集成测试中编写了单元测试。单元测试工作正常,但集成测试给出以下错误:
错误: MeEndpointsTest#test_me / prescriptions_post_endpoint_throws_an_error_when_wrong_params: AbstractController :: ActionNotFound:找不到Spree :: Api :: MeController的动作'create_prescription' test / integration / me_endpoints_test.rb:68:在'block in'中
这意味着他找不到另一个模块中定义的MeController。如何定义MeController是如何进行检查的,因为下面的代码对我没有任何帮助:
if defined? Spree::Api::MeController.class
end
答案 0 :(得分:0)
这最终有效:
def class_defined?(klass)
Object.const_get(klass)
rescue
false
end
if class_defined? 'Spree::Api::MeController'
....
end
答案 1 :(得分:0)
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
<Mvx.MvxAutoCompleteTextView
android:id="@+id/actSignal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:completionThreshold="1"
local:MvxItemTemplate="@layout/searchitemview"
local:MvxBind="ItemsSource Items; PartialText ItemSearchTerm; SelectedObject Item;" />