代码之家  ›  专栏  ›  技术社区  ›  Andres

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

  •  -1
  • Andres  · 技术社区  · 6 年前

    我有两个模型叫做 Contract Appendix . 后者有范围 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
    

    示例:

    contract.appendixes 返回与相同的 contract.appendixes.persisted 尽管在byebug之前,新的非持久化附录已经初始化,这应该会有所不同(?):

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

    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" = $1 AND (id IS NOT NULL) LIMIT $2  [["contract_id", "b3a1645b-d4b1-4f80-9c43-6ddf3f3b7aba"], ["LIMIT", 11]]
     => #<ActiveRecord::AssociationRelation []>
    

    我用 FactoryBot 属性直接初始化对象到DB以防万一(我以前完全通过FactoryBot初始化对象,但后来我认为FactoryBot可能不会以通常的方式与DB交互,这在FactoryBot的 documentation

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

    • 红宝石2.5.1p57
    • 轨道5.1.6
    1 回复  |  直到 6 年前
        1
  •  2
  •   Andres    6 年前

    我担心我可能 .reload 拜访 contract 测试时意外出现规范中的对象。因此我想 “塞尔吉奥”和“阿尤希”指出的部分实际上起了作用,谢谢你的提及!

    我也在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