Reputation: 1481
Learning how to create foreign keys at the database, I had these two models:
class Bar < ApplicationRecord
has_many :foos
end
# and
class Foo < ApplicationRecord
belongs_to :bar
end
Then, I created the following foreign key:
add_foreign_key :foos, :bars, on_delete: :cascade
Therefore, if I delete a bar
it should also delete the foos
that referenced it (and it really did). But I wanted to create a test for it, so I did this:
foo = create(:foo) # a factory that creates a foo with a bar parent
bar = foo.bar
bar.destroy
expect(foo).to_not be_persisted
And surprisingly it didn't work. And then instead of expect(foo).to_not be_persisted
I tried this just to be sure:
expect(Foo.all.size).to eq 0
expect(Foo.count).to eq 0
expect(Foo.all).to_not include foo
And it worked! So my question is: Why be_persisted?
didn't work? Shouldn't it verify if foo
is actually saved at the database?
Upvotes: 1
Views: 437
Reputation: 3610
You need to be aware that by using SQL cascade rules ActiveRecord won't be aware of it.
If you had specified in the model itself something like
has_many: :foos, dependent: :destroy
instead of using an SQL FK cascade rule .. then ActiveRecord would have cascaded the delete and been aware of it.
In your rspec test after doing bar.destroy
do something like expect(Foo.find(foo.id)).to be_nil
instead to test the existence of the child record - or maybe foo.reload
may give you a nil object too.
Upvotes: 1