使用Rails 4.1.4,Ruby 2.1.1
因此,我们有一个需要访问外部API的rails应用程序。我们现在无法在本地运行其他应用程序以简化此操作。我们使用VCR编写测试,但在开发过程中,我们创建了一个FakeMyModel类,就像api一样,我们已经逐渐用MyModel替换它,它调用真正的api。但是在开发过程中,继续使用FakeMyModel然后让Production使用MyModel会很不错。这是我们迄今为止最好的解决方案:
# Settings.yml
api:
model_name: MyModel
# DevelopmentSettings.yml
api:
model_name: FakeMyModel
# config/initializers/local_apis.rb
Api = Settings.api.model_name.constantize
# app/controllers/some_controller.rb
Api.my_method
# models/my_model.rb
class MyModel
def my_method
# Api call here
end
end
# models/fake_my_model.rb
class FakeMyModel
def my_method
{ some: 'default_data' }
end
end
这实际上效果很好,除非有时我们会收到此错误:
ArgumentError - MyModel的副本已从模块树中删除但仍处于活动状态!:
我的理解是因为我们在配置中初始化我们的类,它在开发期间不会重新加载。但是在类本身内部我们调用其中的方法,并且由于该类实际上在models文件夹中,因此它会在开发中动态重新加载,并导致此问题。我看到的唯一解决方案是不要将这样的代码放在不动态重载的地方(比如lib,在本例中为config)。
那我该怎么做呢?我怎么能有一个假的和真正的api类被称为依赖于env,而没有在env的支票中包装每个调用?