在更新操作中调用ActiveRecord .reload方法导致spec对象的ID为nil

时间:2018-07-24 21:54:57

标签: ruby ruby-on-rails-4 rspec controller factory-bot

问题已解决

添加.reload以防止dog_vaccination_records使用不同的数据两次保存到数据库后,我的一些规范由于相同的错误而失败:

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'

在失败的规范内设置断点并调用dog_medical_recordsdog_vaccination_records确实会返回两个带有nil id的对象,但否则会更正信息:

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

导致.reload的原因是什么导致测试数据库中对象的ID为nil?如果我在create中调用nil,则.reload的ID就有意义,但是为什么在更新中该对象不在数据库中?

我做了一些谷歌搜索,想知道该错误是否与.reload无关,只是重新加载“控制台环境中的最新代码”而不是“重新初始化现有对象”。 {3}}。

TL:DR:帮助我了解.reload方法的工作原理,这应该使我更好地了解.reload如何影响我的规格。

通过FactoryGirl初始化规范中的dog_medical_record:

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

DogMedicalRecords控制器更新操作:

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

编辑2018年7月26日

问题是我本该使用.build时使用.create来构建FactoryBot对象。 .build就像在没有.new的情况下调用.save,而使用.create则创建对象并将其保存到数据库。

1 个答案:

答案 0 :(得分:0)

已解决

问题是,当我应该使用.create时,我正在使用.build来构建FactoryBot对象。 .build就像在不使用.save的情况下调用.new一样,而在使用.create时会创建对象并将其保存到数据库source