Reputation: 16335
I encountered a strange behavior when I run specs.
This code doesn't work (baz.viewed
is not updated) unless I uncomment line baz.reload
.
describe "#..." do
it "..." do
baz = user.notifications.create!(title: "baz")
baz.update_attribute(:created_at, Time.now + 3.day)
# it sets `viewed` to `true` in the model to which `baz` is referred.
user.dismiss_latest_notification!
# baz.reload
baz.viewed.should == true
end
end
I don't run specs using Spork
or Guard
, but this model isn't reloaded anyway.
Why it might happening? Or, is it normal practice to invoke .reload
methods in specs?
Upvotes: 0
Views: 262
Reputation: 15788
Let me make this case a bit clearer for you:
When the line baz = user.notifications.create!(title: "baz")
gets executed, two things happen:
1- A new notification row is added to the DB.
2- An object is created in memory, representing this row, and may be referenced with the variable baz
.
Note that baz
has a viewed value of false (and so does the row in the meantime).
Now I didn't see the actual implementation of the method
user.dismiss_latest_notification!
But since you are not passing any variable to it I surely know you have a code in the spirit of:
def dismiss_latest_notification!
latest_notification = self.notifications.last
latest_notification.viewed = true
latest_notification.save!
end
The important line here is
latest_notification = self.notifications.last
An object is created in memory, representing the same row baz
does, but stored in another variable - latest_notification.
Now you have two variables representing the same row in DB. When you perform the save on latest_notification the DB is updated with the right viewed value but the variable baz
is not updated in any manner to reflect this change. You have no choice but to force the update from the DB with the latest values by executing reload
on it.
I think the right way to get rid of the reloading is to change the test a little bit:
Instead of
baz.viewed.should == true
Use:
user.notifications.last.viewed.should be_true
In my opinion, it better suits the purpose of this specific test.
Upvotes: 4