Derek Hill
Derek Hill

Reputation: 6454

Testing before_save with RSpec and Factory Girl

I'm using a before_save call to update all the records that belong to a particular master. Both have a field called item_id:

class Master < ActiveRecord::Base
  has_many :records
  before_save :update_records
  def update_records
    self.records.find_each do |r|
      r.item_id = self.item_id
      r.save
    end
  end
end

class Record < ActiveRecord::Base
end

This works as intended (leaving aside for the minute whether it's a good idea to do something like this). However I can't get an RSpec test that passes. This is what I tried:

describe Master do
  describe 'before_save' do
    it 'updates records belonging to it' do
      master = FactoryGirl.create(:master, item_id: 1)
      record = FactoryGirl.create(:record, master_id: master.id, item_id: 1)
      master.item_id = 2
      master.save
      record.item_id.should == 2
    end
  end
end

The reason is interesting. The model does its work on a second instance of a Record model which gets saved successfully, but is not returned to the spec:

"MASTER - CREATED IN SPEC"
#<Master:0x007fd0ed55ec20> {
    :id => 26,
    :item_id => 1,
}
"RECORD - CREATED IN SPEC"
#<Record:0x007fd0ea157e40> {
    :id => 16,
    :item_id => 1,
    :master_id => 26,
}
"RECORD - AFTER SAVE IN MODEL"
#<Record:0x007fd0ed2f9a70> {
    :id => 16,
    :item_id => 2,
    :master_id => 26,
}
"MASTER - UPDATED IN SPEC"
#<Master:0x007fd0ed55ec20> {
    :id => 26,
    :item_id => 2,
}
"RECORD - FINAL IN SPEC"
#<Record:0x007fd0ea157e40> {
    :id => 16,
    :item_id => 1,
    :master_id => 26,
}

Do you know:

Upvotes: 1

Views: 3100

Answers (1)

Mori
Mori

Reputation: 27779

It looks like your record is just showing you old data, and needs to be refreshed. Try:

record.reload.item_id.should == 2

Upvotes: 5

Related Questions