2010-12-04 98 views
0

我将我的数据库中的关系从has_many更改为has_many:through。所以现在我有:通过db:migrate更改结构数据库后,Rails如何执行数据更新?

class Brand < Ar::Base 
    has_many :products 
end 

class Product < AR::Base 
    belongs_to :brand 
end 

我打算添加一个连接表。

但是当然我需要用数据更新数据库。我已经看到,在迁移的范围内这样做并不是一个好习惯。在数据更新完成后(即从产品表中删除原始brand_id列),我知道必须在数据更新完成后再运行另一次迁移,这是执行此操作的最佳位置?

回答

2

除非我误解了你的问题,否则迁移是进行转换的地方。迁移的目的是更改模式并迁移现有数据以使用模式。迁移捕获分层模式更改的时间方面,以便您可以及时前进和后退,而不会使数据处于不一致的状态。如果您要在其他地方迁移行,则无法保证在代码运行时架构与您编写迁移代码时的架构相同。

我相信你会在Active Record Migrations api文档的例子中找到对我的立场的支持。您可能会将迁移与填充的种子数据混淆(rake db:seed),这是在db/seeds.rb中处理的。

+0

看起来他想运行迁移(添加连接表),然后操作表中的数据,然后再运行另一个迁移。种子是为了传播最初的数据而添加的,但这不是他想要达到的目标......他想操纵现有的数据。有些人认为你不应该用迁移来操纵表中的数据,只能使用表本身。 – johnmcaliley 2010-12-04 20:56:50

+1

我会争辩说,这样做的正确位置应该在一次迁移中。运行与首次迁移相关的更改,迁移数据,然后运行其余的更改。如果这三个步骤相互联系,那么任何一个都不应该独立发生,它们应该包含在一个迁移中。 – 2010-12-04 21:09:22

1

我认为您至少应该包含对迁移中运行数据操作的代码(可能是rake任务)的调用,因为您必须在数据操作后立即运行第二次迁移。

如果是我,我会创建一个操纵数据的rake任务。这将至少从迁移中删除代码,并允许您在必要时手动运行代码。然后编写您的迁移代码并包含对该rake任务的调用。我真的不明白在迁移中不使用数据操作的重大问题。尤其是当你必须按照特定的顺序做事情时。他们紧紧地绑在一起,为什么要将他们彻底分开?

2

像这样的一次性更改可以在迁移中使用ruby代码完成。迁移不仅适用于模式更改。这个想法是,通过版本/日期代码确保迁移只能运行一次。