无法访问 RSpec 中的非持久关联
Can't access non-persisted associations in RSpec
问题: 我有两个型号 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
示例:
当达到 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).
问题:如何从我的规范中的合约对象中读取非持久性附录?
我用:
- Ruby 2.5.1p57
- Rails 5.1.6
- RSpec 3.8.0
- 工厂机器人 4.11.0
- 工厂机器人Rails 4.11.0
恐怕我在测试时可能 .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
问题: 我有两个型号 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
示例:
当达到 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).
问题:如何从我的规范中的合约对象中读取非持久性附录?
我用:
- Ruby 2.5.1p57
- Rails 5.1.6
- RSpec 3.8.0
- 工厂机器人 4.11.0
- 工厂机器人Rails 4.11.0
恐怕我在测试时可能 .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