0

ISSUE HAS BEEN RESOLVED

After adding .reload in order to prevent the dog_vaccination_records from saving to the database twice with different data, a few of my specs fail with the same error:

Failure/Error: Unable to find matching line from backtrace
     ActiveRecord::RecordNotFound:
       Couldn't find DogVaccinationRecord without an ID
     # ./app/controllers/dog_vaccination_record_controller.rb:9:in `update'

Setting a breakpoint inside of the failing spec and calling dog_medical_records or dog_vaccination_records does indeed return both objects with nil ids, but correct information otherwise:

#<DogVaccinationRecord:0x007fed0bf322d0
id: nil,
dog_record_id: 6,
archived_at: nil,
created_at: nil,
updated_at: nil>

What is it about .reload that causes the id of an object in the test database to be nil? A nil ID would make sense if I called .reload in create, but why in update is that object not already in the database?

I've done a bit of Googling and wonder if the error has anything to do with the .reload only reloading "the latest code in the console environment" and not "re-initializing existing objects" a la this explanation of .reload.

TL:DR: Help me understand how the .reload method works, which should give me a better idea of how .reload is affecting my specs.

Initialization of dog_medical_record in the spec via FactoryGirl:

dog_vaccination_record = FactoryGirl.build(:dog_vaccination_record_base, dog_medical_record: dog.dog_medical_record)

DogMedicalRecords controller update action:

def update
  @dog_vaccination_records = @dog.dog_record.dog_vaccination_records.decorate
  if @dog_medical_records.update_attributes(params[:dog_medical_records])
    @dog_vaccination_records.reload.update_attributes(params[:dog_vaccination_records]) if params[:dog_vaccination_records]

    @dog_medical_records.errors.add(:dog_vaccination_records, "fields are not valid") unless @dog_vaccination_records.valid?
    initialize_resource
  end

respond_with @dog_medical_records
end

EDIT 07/26/2018

The issue was that I was using .build to build a FactoryBot object, when I should have used .create. .build is like calling .new without a .save, while using .create creates the object and saves it to the database.

S. Causey
  • 1
  • 3
  • 1
    Your `@dog_vaccination_records` is not saved in the database to begin with (from what you've shown us). So it can't be reloaded. – Sergio Tulentsev Jul 24 '18 at 21:58
  • 1
    Also, aren't you confusing `reload!` from rails console and `reload` from ActiveRecord? – Sergio Tulentsev Jul 24 '18 at 22:00
  • Sorry @SergioTulentsev, I've had to refactor this code a bit to protect the project. I've fixed all mentions of `.reload!` to just `.reload` as it is in the controller's update action. Yes, I was confusing it with the ActiveRecord method. – S. Causey Jul 24 '18 at 22:04
  • @SergioTulentsev, I was about to ask you what you meant by `@dog_vaccination_records` not being saved to begin with. But then I changed that `FactoryGirl.build()` to `FactoryGirl.create` and the ID appears. That's what you were talking about, wasn't it? The difference between `.build` and `.create`? – S. Causey Jul 24 '18 at 22:15
  • Exactly that, yes. – Sergio Tulentsev Jul 24 '18 at 22:21
  • That's the crucial part of your question - that you've used FactoryBot's `build` instead of `create`. Care to update the question for others to find? – Greg Jul 25 '18 at 10:32
  • Thanks for your help, @SergioTulentsev and question has been updated – S. Causey Jul 25 '18 at 15:06

1 Answers1

0

RESOLVED

The issue was that I was using .build to build a FactoryBot object, when I should have used .create. .build is like calling .new without a .save, while using .create creates the object and saves it to the database source.

S. Causey
  • 1
  • 3