/ 30.Jan.2007
Rails 1.2 added native support for fixed decimal variables using the BigDecimal class. This is great news for anyone who needed to deal with currency in their Rails applications because it means we can move away from storing fixed decimal values as integers in the database.
But wouldn't it be nice if you could automagically migrate your existing fixed decimal columns to use the new-fangled decimal type?
I sure thought it would be, so I wrote a couple of migration helper methods so that I could write a one-liner in a migration file to convert a column from fixed decimal as integer to a real decimal column. All the gory details are available after the jump.
I apologize if reading this post made your eyes glaze over.
Here is a usage example from a migration script I wrote. It's pretty straightforward, you just feed the method the model it's working with, the existing column name, and the new column name.
require "migration_helpers"
class ChangePriceColumnsToDecimal < ActiveRecord::Migration
extend MigrationHelpers
def self.up
decimalize_column(Item, :price_in_cents, :price)
end
def self.down
undecimalize_column(Item, :price_in_cents, :price)
end
end
And here are the actual helper methods. These should be placed in lib/migration_helpers.rb for your app. (Create the file if you don't have one already.)
module MigrationHelpers
def decimalize_column(model_name, old_column, new_column)
rename_column model_name.table_name, old_column, new_column
change_column model_name.table_name, new_column, :decimal, :precision => 8, :scale => 2
model_name.reset_column_information
model_name.find(:all).each do |row|
unless row[new_column] == nil
row.update_attribute new_column, row[new_column] / 100
end
end
end
def undecimalize_column(model_name, old_column, new_column)
model_name.find(:all).each do |row|
unless row[new_column] == nil
row.update_attribute new_column, row[new_column] * 100
end
end
change_column model_name.table_name, new_column, :integer
rename_column model_name.table_name, new_column, old_column
end
end
Hope someone else finds this helpful.
micro theme by seaofclouds, and powered with Mephisto
1 Comment
Leave a Comment