You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5.1.7升级后如何修复`uninitialised constant 'ActiveRecord_Relation'`错误?

解决Rails 5.1升级后BusinessType::ActiveRecord_Relation未定义的问题

这个问题是Rails 5.1对ActiveRecord关联对象的类结构做了核心改动导致的——在Rails 5.0中,每个模型的Relation对象会动态生成一个嵌套的Model::ActiveRecord_Relation类,但Rails 5.1移除了这个机制,所有Relation对象统一使用顶层的ActiveRecord::Relation类,仅通过内部属性关联对应的模型。

解决方案:修改测试中的类型匹配逻辑

你需要把测试里的kind_of(BusinessType::ActiveRecord_Relation)替换为对ActiveRecord::Relation的检查,同时验证其关联的模型是BusinessType。有几种简洁的写法可以实现:

方法1:用satisfy匹配器验证模型类

修改测试代码如下:

describe 'GET #index' do
  it 'initialises the view model with the correct arguments' do
    expect(BusinessTypes::Index).to receive(:new)
      .with(
        an_instance_of(ActiveRecord::Relation).and(satisfy { |rel| rel.model == BusinessType }),
        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(
          an_instance_of(ActiveRecord::Relation).and(satisfy { |rel| rel.model == BusinessType }),
          user,
          address_confirmed: false
        )
      get :index
    end
  end
end

方法2:用have_attributes匹配器简化写法

如果你更喜欢更紧凑的表达,可以直接检查Relation内部的klass属性(和model方法等价,用于存储关联的模型类):

.with(
  kind_of(ActiveRecord::Relation).and(have_attributes(klass: BusinessType)),
  user,
  address_confirmed: true
)

验证改动的合理性

你可以在Rails 5.1的控制台里快速验证这个变化:

# 查看Relation对象的实际类
BusinessType.all.class # => ActiveRecord::Relation
# 查看关联的模型类
BusinessType.all.model # => BusinessType
BusinessType.all.klass # => BusinessType

而在Rails 5.0中,BusinessType.all.class会返回BusinessType::ActiveRecord_Relation,这就是旧测试在升级后失效的核心原因。

额外优化:封装自定义匹配器

如果项目中有多处类似的测试,可以封装一个自定义RSpec匹配器,让代码更整洁:

RSpec::Matchers.define :be_a_relation_of do |expected_model|
  match do |actual|
    actual.is_a?(ActiveRecord::Relation) && actual.model == expected_model
  end
end

之后就能在测试里直接用be_a_relation_of(BusinessType),替代冗长的匹配逻辑。

内容的提问来源于stack exchange,提问作者edmunteanu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:13:06