我有一个下表叫做feeds
:
from_type | from_id
-----------+---------
user | 1
project | 1
user | 2
program | 1
program | 2
project | 1
challenge | 1
project | 3
community | 1
而且我想将其转换为:
from_type | user_id | project_id | program_id | challenge_id | community_id
-----------+---------+------------+------------+--------------+-------------
user | 1 | | | |
project | | 1 | | |
user | 2 | | | |
program | | | 1 | |
program | | | 2 | |
project | | 1 | | |
challenge | | | | 1 |
project | | 3 | | |
community | | | | | 1
我这样做的原因是,如果需要回退,请进行反向迁移。我设法用coalesce + update statement
将底部版本转换为顶部版本,但是我不确定如何执行反向操作。
这里是向上迁移,向下迁移应该是什么样?
class PolymorphicFeedTable < ActiveRecord::Migration[5.2]
def up
execute <<-SQL
UPDATE feeds SET
from_id = coalesce(user_id, project_id, community_id, challenge_id, program_id, need_id);
SQL
end
def down
execute <<-SQL
?
SQL
end
end
如果您展开up
方法:
def up
%w[challenge community need program project user].each do |type|
execute("update feeds set from_id = #{type}_id where from_type = '#{type}'")
end
end
然后您可以看到前进的方向,只需逆转分配:
def down
%w[challenge community need program project user].each do |type|
execute("update feeds set #{type}_id = from_id where from_type = '#{type}'")
# ------------------------^^^^^^^^^^^^^^^^^^^^
end
end
[假设您的表数据没有损坏(即from_type
值与X_id
列匹配)。
您可以connection.quote(type)
,而不是简单地手工将#{type}
用单引号引起来,但是您知道类型是安全的,因此没有必要。对于connection.quote_column_name
和#{type}_id
插值类似。