如何解决在迁移中使用重命名的列
在 Rails 6.1 中,我想重命名列并在一次迁移中转换底层数据:
class RestructureExamples < ActiveRecord::Migration[6.1]
def up
rename_column :examples,:old_column_name,:new_column_name
Example.reset_column_information
Example.find_each do |example|
unless example.new_column_name.nil?
if example.new_column_name == 100
example.new_column_name = 300
else
example.new_column_name = (example.new_column_name.to_f * 2.989).to_i
end
end
end
end
def down
# Do the reverse - left out for brevity
end
end
即使添加了 reset_column_information
(来自文档:“重置有关列的所有缓存信息,这将导致它们在下一个请求时重新加载。”),这会抛出 NoMethodError: undefined method `new_column_name'
。>
记录 example
仍然有 old_cloumn_name
。我期望在将 rename_column
一起调用 with reset_column_information
后,在数据库和模型中更新列信息。
我可以在 sources 中看到 rename_column
执行了一个 alter table sql 命令。在 rename_column
后通过 sql 检查列名称显示该列已正确重命名。所以,我假设只有模型包含过时的信息。
可能有几种解决方法(使用 sql 而不是模型,在转换数据后重命名,使用两个单独的迁移,...),但我更喜欢我的方法来提高可理解性。
解决方法
如果你想让它像你现在使用的那样工作,你必须在 change_table
中重命名它。
change_table :examples do |t|
t.rename :old_name,:new_name
end
Example.reset_column_information
# ....
,
我想我找到了我自己问题的答案。正如 migrations guide 中所建议的,可以将本地模型与 reset_column_information
结合使用:
class RestructureExamples < ActiveRecord::Migration[6.1]
class Example < ActiveRecord::Base
end
def up
rename_column :examples,:old_column_name,:new_column_name
Example.reset_column_information
Example.find_each do |example|
unless example.new_column_name.nil?
if example.new_column_name == 100
example.new_column_name = 300
else
example.new_column_name = (example.new_column_name.to_f * 2.989).to_i
end
end
end
end
def down
# Do the reverse - left out for brevity
end
end
这种方法对我有用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。