使用 rake db:migrate 迁移数据不会改变它

Mar*_*cak 5 ruby ruby-on-rails database-migration dbmigrate

我正在为 rails 和 db:migrate 苦苦挣扎。我有这个代码的迁移

class SetDefaultInstallmentsForLicenses < ActiveRecord::Migration
  def up
    License.where(code: 'LEADER').each do |leader|
      puts "Modifying license #{leader.id} with code #{leader.code}"
      leader.installment_available = true
      leader.installment_number = 5
      leader.save
      puts "After save #{leader.installment_available} #{leader.installment_number}"
      leader = License.find(leader.id)
      puts "After save #{leader.installment_available} #{leader.installment_number}"
    end
  end

  def down
  end
end
Run Code Online (Sandbox Code Playgroud)

运行迁移后有这个输出

==  SetDefaultInstallmentsForLicenses: migrating ==============================
Modifying license 3 with code LEADER
After save true 5
After save f
==  SetDefaultInstallmentsForLicenses: migrated (0.0037s) =====================
Run Code Online (Sandbox Code Playgroud)

可以清楚地看到执行迁移,找到记录,更改并保存,但重新加载记录后,更改不存在。怎么了?

Kir*_*rat 6

  leader.save
  puts "After save #{leader.installment_available} #{leader.installment_number}"
  ==> After save true 5  
Run Code Online (Sandbox Code Playgroud)

以上仅显示installment_availableinstallment_number字段的值,而local variable leader不是从数据库中提取值。这并不意味着这些字段已成功保存在数据库中。

  leader = License.find(leader.id)
  puts "After save #{leader.installment_available} #{leader.installment_number}"
Run Code Online (Sandbox Code Playgroud)

但是上面是从数据库中获取记录并清楚地表明更新没有保存在数据库中。

而不是leader.save,使用leader.save!。这样,如果记录没有保存,那么您将确切知道为什么由于引发的异常而没有保存它。

更新

根据 OP 对这个问题的回答

我试着把

License.reset_column_information

在代码之前,它现在似乎正在工作。我不知道为什么这里需要这个。我所有的其他迁移似乎都在正常工作。

我做了一点研究,究竟License.reset_column_information做了什么。我发现在你的迁移中使用模型它说:

使用本地模型时,最好在更新数据库中的数据之前调用 Product.reset_column_information 来刷新 Product 模型的 Active Record 缓存。

希望这可以帮助您理解为什么License.reset_column_information需要。