Rafael Costa
Rafael Costa

Reputation: 1481

Why be_persisted? doesn't perceive database changes? on rails

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

Answers (1)

David
David

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

Related Questions