无法访问 RSpec 中的非持久关联

Can't access non-persisted associations in RSpec

问题: 我有两个型号 ContractAppendix。后者的范围 persisted 用于排除非持久对象。我想为范围编写规范,但似乎我根本无法访问规范内的非持久关联。

型号:

class Contract < ApplicationRecord
  has_many :appendixes
end

class Appendix < ApplicationRecord
  belongs_to :contract
  scope :persisted, -> { where 'id IS NOT NULL' }
end 

附录模型规格:

context 'within persisted scope' do
  it 'returns only persisted appendixes' do
    contract = Contract.create(attributes_for(:contract))
    Appendix.create(attributes_for(:appendix, contract: contract))
    contract.appendixes.new
    byebug
  end
end

示例:

当达到 byebug 断点时,contract.appendixes returns 与 contract.appendixes.persisted 相同,尽管在 byebug 之前,新的非持久性附录被初始化,这应该有所不同( ?):

(byebug) contract.appendixes
#<ActiveRecord::Associations::CollectionProxy []>
(byebug) contract.appendixes.persisted
#<ActiveRecord::AssociationRelation []>

同时,在 rails 控制台中重复相同的规范时,它按预期工作:

2.5.1 :061 > c = Contract.last
2.5.1 :062 > c.appendixes
 => #<ActiveRecord::Associations::CollectionProxy []>
2.5.1 :063 > c.appendixes.new
 => #<Appendix id: nil, ...
2.5.1 :064 > c.appendixes
 => #<ActiveRecord::Associations::CollectionProxy [#<Appendix id: nil, ...
2.5.1 :065 > c.appendixes.persisted
  Appendix Load (1.6ms)  SELECT  "appendixes".* FROM "appendixes" WHERE "appendixes"."contract_id" =  AND (id IS NOT NULL) LIMIT   [["contract_id", "b3a1645b-d4b1-4f80-9c43-6ddf3f3b7aba"], ["LIMIT", 11]]
 => #<ActiveRecord::AssociationRelation []>

我用FactoryBot attributes for initializing objects directly to DB just in case (I previously initialized the object through FactoryBot completely but then I thought that FactoryBot might not interact with DB the usual way, this is also said in FactoryBot's documentation).

问题:如何从我的规范中的合约对象中读取非持久性附录?

我用:

恐怕我在测试时可能 .reload 不小心调用了规范中的 contract 对象。因此,我猜想@Sergio 和@ayushi 指出的 cache 部分实际上在其中发挥了作用,感谢您的提及!

我也在 FactoryBot 的帮助下编写了规范,因此无需将其排除在这种情况之外:

context 'withing persisted scope' do
  it 'returns only persisted appendixes' do
    contract = create(:contract)
    appendix = contract.appendixes.new
    expect(contract.appendixes).to include(appendix)
    expect(contract.appendixes.persisted).not_to include(appendix)
  end
end