Rails/Ruby 如何覆盖迁移方法 timestamps?

5
我正在尝试编写自己的时间戳方法,并在迁移期间运行。现有的方法会在字段上添加NOT_NULL约束,而我确实不希望这样做。
问题在于我有一个多模式数据库。每个主要客户都有自己的模式。当我们接受一个新客户时,我们创建一个新租户记录,然后为一个新创建的模式运行迁移。新模式应该是其他模式中表的精确副本,当然没有数据。
我运行的最后一次迁移使用的是稍旧版本的Rails。仍然是3版本系列但略旧。当它创建时间戳时,它们是可以为空的。当我最近在一个新版本的Rails上运行迁移时,所有字段都变成了NOT_NULL。
我的代码是按照更新记录时才填充updated_at的想法开发的(第三方应用程序和数据库“函数”创建记录)...创建记录的第三方应用程序和数据库函数在新模式上失败了。我已经手动删除了所有表上的NOT_NULL约束,但我不想将清理直接编写到我的迁移任务中,以便所有未来的表都得到修正。
我想最好的办法是将被更改的timestamps方法覆盖回到没有破坏现有代码的方法。
因此,我需要恢复/覆盖的原因就在这里...现在我的问题是...我该如何覆盖这个方法。我看不到明确的类路径,并且不确定如何覆盖它。
2个回答

4
把它放在一个猴子补丁里... 很简单!
class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::TableDefinition
  def timestamps(*args)
    options = args.extract_options!
    column(:created_at, :datetime, options)
    column(:updated_at, :datetime, options)
  end
end

如Maniek所说,由于这个“修复”程序,Rails的更新将被忽略。
但他最初提供的解决方案也是如此。此外,为了适应他的解决方案,您需要回到旧的迁移并用新代码替换“时间戳”。除此之外,您还需要替换所有未来自动生成的迁移。
我认为这不符合DRY原则,也不符合SPOT原则。
要小心!

1

有什么问题:

create_table :foo do |t|
   t.text :bar
   t.datetime :created_at
   t.datetime :updated_at
end

?


我已经有超过50个迁移文件了,我不想一个一个地修改它们以适应这种模式。我也不想改变Rails创建脚手架的代码,以便它插入错误的日期时间戳而不是时间戳。 - baash05
3
@daveatflow,更改迁移肯定比打出问题描述要快得多 :) 至于要覆盖哪里:当然可以启用调试运行rake任务。在create_table块中放置一个debugger调用,步入timestamps方法,你应该能够获取文件位置。个人并不推荐这样做,因为这也可能会在未来的Rails版本中发生变化。 - maniek
就像我说的,我有超过50个迁移,我必须更改它们所有以及Rails生成的所有未来迁移。我还必须记录其他人必须更改Rails创建的迁移。调试器逻辑...那真是太聪明了。为了避免将来版本的更改,我正在特别努力。如果他们更改字段名称(例如),那么我有一个数据库,两个模式应该是相同的,但具有不同的字段名称。 - baash05
@daveatflow 未来的 Rails 版本可能会发生变化,例如他们可能决定将逻辑移动到类 Bar 中,而您仍在猴子补丁 Foo。 - maniek
如果老天愿意的话,在那之前我会一直使用Java进行编程。 - baash05

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接