Home > front end >  RSpec: factory not persisting after attribute changes?
RSpec: factory not persisting after attribute changes?

Time:03-25

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.typetoactiveand.object_status_idto15`) 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
  • Related