Проблема: У меня есть две модели: 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
возвращает то же самое, что и 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" = $1 AND (id IS NOT NULL) LIMIT $2 [["contract_id", "b3a1645b-d4b1-4f80-9c43-6ddf3f3b7aba"], ["LIMIT", 11]]
=> #<ActiveRecord::AssociationRelation []>
Я использую атрибуты FactoryBot для инициализации объектов непосредственно в БД на всякий случай (ранее я полностью инициализировал объект через FactoryBot, но потом я подумал, что FactoryBot может не взаимодействовать с БД обычным образом, об этом также говорится в документация FactoryBot).
Вопрос: Как я мог прочитать непостоянные приложения из объекта-контракта внутри моих спецификаций?
Я использую:
Действительно, похоже, что это должно было сработать
Ваш консольный тест делает что-то немного другое. Сначала он вызывает contact.appendixes
(который, вероятно, помещает их в кеш)
Боюсь, что .reload
мог случайно вызвать объект contract
в спецификации во время тестирования. Из-за этого я думаю, что часть тайник, на которую указали @Sergio и @ayushi, действительно сыграла роль в этом, спасибо за упоминание!
Мне тоже удалось написать спецификацию с помощью 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
Я нашел прицел отсюда: stackoverflow.com/a/19845632/1677069