如何在Rails 5.1.7中修复`uninitialised constant'ActiveRecord_Relation'`?

问题描述 投票:2回答:1

手头的问题

我目前正在将我们的一个项目中的Rails版本从5.0.7升级到5.1.7,但我似乎无法找到解释为什么以前工作的调用BusinessTypes::ActiveRecord_Relation不再起作用。此调用作为规范的一部分执行,以检查控制器是否正确初始化具有正确参数的视图模型(以及具有正确类的ActiveRecord::Relation)。

我试过的

  1. 我试图使用rails控制台检查源代码/文件,但无济于事,因为我似乎没有找到任何来源。我试过以下命令: show-source BusinessTypes::ActiveRecord_Relation BusinessTypes::ActiveRecord_Relation.source_location
  2. 我已经尝试在Google和Rails repos(5.0-stable和5.1-stable)中搜索ActiveRecord_Relation子类,但我没有找到任何东西,只有ActiveRecord::Relation类本身,这对我的问题没有任何帮助。
  3. 我也检查了更改日志,但没有任何东西让我觉得它对此产生了影响。

代码洞察力

测试方法BusinessTypes#index看起来像这样:

def index
  @vm = BusinessTypes::Index.new(@business_types.all, current_user, address_confirmed: address_confirmed?)
end

错误的规范看起来像这样:

let(:user) { create(:user) }

describe 'GET #index' do
  it 'initialises the view model with the correct arguments' do
    expect(BusinessTypes::Index).to receive(:new)
      .with(kind_of(BusinessType::ActiveRecord_Relation), user, address_confirmed: true)
    get :index
  end

  context 'user has not confirmed his address' do
    let(:user) { create(:user, address_confirmed_at: nil) }

    it 'initialises the view model with the correct arguments' do
      expect(BusinessTypes::Index).to receive(:new)
        .with(kind_of(BusinessType::ActiveRecord_Relation), user, address_confirmed: false)
      get :index
    end
  end
end

预期与实际结果

Rails version 5.0.7

此测试将通过,因为kind_of(BusinessTypes::ActiveRecord_Relation)将返回一个对象#<RSpec::Mocks::ArgumentMatchers::KindOf:0x00007fe52529ae20 @klass=BusinessType::ActiveRecord_Relation>,该对象与控制器作为参数传递的对象一致。

Rails version 5.1.7

我收到以下错误:NameError: uninitialized constant BusinessTypes::ActiveRecord_Relation

两种情况之间唯一改变的是Rails版本。我监督过什么吗?感谢您的时间!

ruby-on-rails ruby activerecord
1个回答
0
投票

问题是ActiveRecord_Relation被定义为BusinessType内部的私有常量。你不能在BusinessType之外引用它。

https://www.rubydoc.info/stdlib/core/Module:private_constant

https://github.com/rails/rails/blob/f40860800c231ecd1daef6cf6b5a8a8eda76478d/activerecord/lib/active_record/relation/delegation.rb#L25

但是你可以像这样引用它:

BusinessTypes.const_get("ActiveRecord_Relation")

但我不会在测试中以这种方式引用它。我认为更好的方法是:

expect(BusinessTypes::Index).to receive(:new).with(kind_of(BusinessType.all.class), # ...
© www.soinside.com 2019 - 2024. All rights reserved.