我正在开发一个web应用程序,它已经有了一个带有一定数量表(a,b,c…)的模式(aka in prod)。
表A有一个与表B中的enum
相对应的属性。问题是,在表A的专用列中,我只能有一个enum
列表项。但我希望表A中的对象有许多。所以我创建了一个连接表a_b和一个与表b的关联。
第一个结果是,我需要用以前模式体系结构的数据填充联接表。更清楚地说,它们是表A中与表B枚举的一个元素关联的对象。我需要在新创建的联接表中报告这些简单关系(表B中has_many through
列表中只有一个元素与表A对象关联)。
以下是我想做的事情:
list_of_ids = []
Model_A.where(attribute: 0).each { |r| list_of_ids << r.id }
a.each { |el| A_B.create(tableA_id: el, tableB_id: 0) }
我应该在哪里编写和执行这些将更新我的数据的代码行?
最佳答案
如我在评论中所述,我将把这个“数据更新”逻辑放在连接表创建的同一个迁移文件中。
为什么在迁移文件中?
在创建联接表之后和删除包含外键的列之前,只需要执行一次数据转换。如果在列移除之后执行此数据转换,则会出现一个错误,即您的代码试图访问不再存在的列。
迁移负责更改数据库结构和数据完整性。
为什么不是耙子任务?
rake任务应该运行多次,而不是只运行一次。通常的任务是“发送电子邮件”、“更新过期日期”、“计算缓存”、“关闭不活动的用户帐户”等。
转换前的数据有很多->habtm必须更新以遵循新的结构。rake任务无法运行,然后数据将不会更新,因此您将丢失模型之间的关联(在运行rake任务之前删除外键列将使您丢失此数据)。
数据转换逻辑必须在迁移创建联接表之后、迁移删除外键的列之前发生。对于你的rails应用程序,有一个明确的说法:“做这个迁移,然后停止,运行这个任务,然后做这个迁移”。它将连续运行迁移。如果有这2个迁移未决,它们将立即运行,除非您指定了其他(通常不常见),然后Rake任务将无效,因为它依赖于外键列仍然存在的事实。