在迁移中使用重命名的列
Using renamed columns in a migration
在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
这种方法对我有用。
在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
这种方法对我有用。