是否可以在Rails迁移中使用自定义列类型?

时间:2009-09-20 14:14:16

标签: ruby-on-rails migration

我必须使用Rails迁移创建数据库模式。

我有很多列包含数量(kg)和价格(货币)。

目前我用这个:

  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 noob,如果这是一个愚蠢的问题,我很抱歉。

2 个答案:

答案 0 :(得分:2)

只是跟进:我最终修补了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

答案 1 :(得分:1)

我确信你可以做你要求的事情 - 深入了解迁移代码中的列方法 - 但我认为它不会自然得到支持。我认为迁移的想法是它们非常接近数据库语言(并且远离您的域模型),因此支持是以数据库为中心的。

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

您还可以在迁移过程中创建帮助方法来干掉它。我一直这样做......迁移只是一个Ruby类,所以你可以创建:

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