Im fairly new to RSpec but I am running into an issue (This is on Rails 4 fwiw). I have a simple model/factory test:
context "Scopes" do
let (:widget) {create(:core_widget)}
it ":active" do
puts "Last Created widget:"
puts pp(Core::Widget.last)
widget.type = "active"
widget.object_status_id = 15
puts "After attribute change:"
puts pp(Core::Widget.last)
#puts pp(widget.attributes)
expect(Core::Widget.active.ids).to include(widget.id)
end
end
This is testing out a very simple scope:
scope :active, -> { where(type: 'active', object_status_id:
[25, 15])
Pretty basic. However I noticed that checking (via the puts
of the factory objectdoes NOT show the attribute changes (Changing
.typeto
activeand
.object_status_idto
15`) when I re-print it?
I was told that let
is lazily evaluated, and I understand that....but when I view the different object_id's when printing they are completely different. let
should still have the same object reference in the same it
block right?
Initially I thought it was a problem because I was doing build_stubbed
on the factory creation. I also tried let!
because I thought maybe that was the problem. Neither worked.
CodePudding user response:
I think what is happening here is that you are updating the attributes of the model in memory without saving the changes to your database. Then when your active
scope is called, a query is made to the database but since your changes haven't been saved to the database yet, the expected record is not found.
I would recommend checking out the various update*
functions as a way to persist your changes to the database, or make sure you call save
to save your changes.
For example, you can update your test to:
it ":active" do
puts "Last Created widget:"
puts pp(Core::Widget.last)
widget.type = "active"
widget.object_status_id = 15
widget.save! # Add this line here to explicitly save the record to the DB
puts "After attribute change:"
puts pp(Core::Widget.last) # Now this should find the changed record in the DB as expected
expect(Core::Widget.active.ids).to include(widget.id)
end