【问题标题】:Is it possible to use a custom column type in a Rails migration?是否可以在 Rails 迁移中使用自定义列类型?
【发布时间】:2009-09-20 14:14:15
【问题描述】:

我必须使用 Rails 迁移创建数据库架构。

我有很多列,其中包含数量(公斤)和价格(货币)。

目前我用这个:

  t.column :quantity, :decimal, :precision => 6, :scale => 3
  t.column :value, :decimal, :precision => 6, :scale => 2

在生成器调用中,我使用quantity:decimal 来标识我的列。然后我手动将生成的t.decimal行改成上面的。

我不喜欢这样,因为在每次生成迁移后,我都必须手动编辑迁移脚本,而且我担心 DRY。 (如果价格必须包含四位而不是两位小数怎么办?)

是否可以创建一个我可以在迁移甚至生成器中使用的自定义列类型,如下所示:

  t.quantity :quantity
  t.price :value

PS:我是 Rails 菜鸟,如果这是一个愚蠢的问题,我很抱歉。

【问题讨论】:

  • “必须手动修复迁移脚本”到底是什么意思?
  • 现在我只在生成器调用中使用“数量:十进制”。然后我必须编辑生成的迁移脚本并将“t.decimal :quantity”更改为上面的示例。 (使用泛型列类型,添加精度参数)

标签: ruby-on-rails migration


【解决方案1】:

只是一个后续:我最终给 Rails 打了猴子补丁:

class ActiveRecord::ConnectionAdapters::TableDefinition

  def price(*args)
    options = args.extract_options!
    options.reverse_merge!({ precision: 8, scale: 2 })
    column_names = args
    type = :decimal
    column_names.each { |name| column(name, type, options) }
  end

end

这让我可以使用price 作为列类型,这样可以实现看起来干净的迁移。

create_table :stuff do |t|
  t.price :my_price
end

【讨论】:

    【解决方案2】:

    我确信您可以按照您的要求进行操作 - 深入研究迁移代码中的 column 方法 - 但我认为它不会自然得到支持。我认为迁移的想法是它们非常接近数据库语言(并且远离您的域模型),因此支持非常以数据库为中心。

    查看使用 with_options (railscasts.com/episodes/42-with-options)。这将允许您在不修补 rails 的情况下完成单个迁移。

    您还可以在迁移中创建辅助方法来将其干燥。我一直这样做...迁移只是一个 Ruby 类,因此您可以创建:

    def 货币(列) add_column :my_table, column, :deci... 等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-24
      • 2019-05-16
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 2013-03-18
      • 2012-05-30
      相关资源
      最近更新 更多