ruby on rails - Active Record Association CollectionProxy not working: why does @owner.@target.count yield a result of 1 when @owner.@target returns an empty array? -
i have models in rails app:
sales_opportunity has_many swots.
i'm setting them using factorygirl , running test show when delete sales_opportunity cause associated swots deleted. reason when debugging byebug i'm getting strange results - sales_opportunity , swot records being correctly created, when run sales_opportunity.swots returns [ ] whereas sales_opportunity.swots.count returns 1. what's more odd exact same code works fine anther object association (timeline_events swots yet work same code).
can tell me doing wrong please?
sales_opportunity.rb:
class salesopportunity < activerecord::base default_scope { order('close_date asc') } belongs_to :user belongs_to :company has_many :key_contacts has_many :timeline_events, dependent: :destroy has_many :swots, dependent: :destroy end
swot.rb:
class swot < activerecord::base belongs_to :sales_opportunity validates :swot_details, presence: true validates :sales_opportunity_id, presence: true enum swot_type: [:strength, :weakness, :opportunity, :threat] enum swot_importance: { minimal: 1, marginal: 2, noteworthy: 3, significant: 4, critical: 5 } validates :swot_importance, presence: true end
swot factorygirl spec:
factorygirl.define factory :swot swot_importance "minimal" swot_details "some boring details" swot_type "threat" trait :attached association :sales_opportunity, :with_user_id end end end
sales_opportunity factorygirl spec:
factorygirl.define sequence(:opportunity_name) { |n| "sales oppotunity - #{n}" } factory :sales_opportunity user opportunity_name {generate(:opportunity_name)} close_date "2014/12/12" sale_value 10000 company_id 7 trait :with_user_id user_id 6 end end end
failing rspec tests:
describe "when swot's parent sales opportunity destroyed" let(:swot) { factorygirl.create(:swot, :attached) } let(:sales_opportunity) { swot.sales_opportunity } "should destroy associated swots" dswots = sales_opportunity.swots.to_a byebug sales_opportunity.destroy expect(dswots).not_to be_empty dswots.each |dswot| expect(swot.where(id: dswot.id)).to be_empty end end end
output console (byebug) when logging swot:
#<swot id: 13, swot_type: 3, swot_importance: 1, sales_opportunity_id: 564, swot_details: "some boring details", created_at: "2015-07-27 10:57:23", updated_at: "2015-07-27 10:57:23">
output console when logging sales_opportunity:
#<salesopportunity id: 564, close_date: "2014-12-12 00:00:00", user_id: 6, created_at: "2015-07-27 10:57:23", updated_at: "2015-07-27 10:57:23", pipeline_status: 0, opportunity_name: "sales oppotunity - 4", company_id: 7, sale_value: #<bigdecimal:7fe9ffd25078,'0.1e5',9(27)>, swot_score: 0>
output sales_opportunity.swots.count:
(byebug) sales_opportunity.swots.count 1
output sales_opportunity.swots:
(byebug) sales_opportunity.swots #<activerecord::associations::collectionproxy []>
i think i've included known info. rspec tests, factorygirl factories , setup between sales_opportunities , swots/timeline_events same - yet rspec tests pass timeline_events , collection_proxy works (so far can tell, code identical):
timeline_event factory:
factorygirl.define factory :timeline_event activity "some activity" due_date "2014/11/11" trait :attached association :sales_opportunity, :with_user_id end end end
working rspec tests:
describe "when sales opportunity destroyed timeline event" let(:timeline_event) { factorygirl.create(:timeline_event, :attached) } let(:sales_opportunity) { timeline_event.sales_opportunity } "should destroy associated timeline events" timeline_events = sales_opportunity.timeline_events.to_a sales_opportunity.destroy expect(timeline_events).not_to be_empty timeline_events.each |event| expect(timelineevent.where(id: event.id)).to be_empty end end end
timeline_event.rb:
class timelineevent < activerecord::base belongs_to :sales_opportunity validates :activity, presence: true validates :due_date, presence: true validates :sales_opportunity_id, presence: true end
when running byebug in same place here array including timeline_event.
can me understand what's going wrong in code?
thanks.
i solved issue - seems sales_opportunity needs reloaded active record associations persisted. this answer key solution.
here's working code:
describe "when swot's parent sales opportunity destroyed" let!(:swot) { factorygirl.create(:swot, sales_opportunity: sales_opportunity) } "should destroy associated swots" sales_opportunity.reload expect { sales_opportunity.destroy }.to change(sales_opportunity.swots, :count).by(-1) end end
using elements of max's answer above helped me improve , feel of code.
Comments
Post a Comment