One of the things I’ve been getting setup this week on my new laptop is my Ruby environment. I went through the Apple Leopard Rails Tutorial and ran into one big hiccup at the end – my tests wouldn’t pass. I had created an app and ran the following:
script/generate scaffold event name:string budget:decimal
However, when I ran rake test:units
I would get a failure that it was expecting 30.50 but was 30. I suspected something to do with decimals or integers, but it turns out that I think there is a bug in Rails.
Basically, you know you’ve run into this whenever your development database has a decimal column with a 0 scale. If you are using MySQL, you *will* run into this, because the default precision and scale for a decimal is (10,0). So, what happens is that when you run generate, you get:
def self.up
create_table :events do |t|
t.string :name
t.decimal :budget, :precision => 10, :scale => 2
t.timestamps
end
end
This works for the creation of the dev database (via rake db:migrate
) but when you run rake test:units
it looks at the dev database and tries to copy over the schema. Seeing that the scale is 0, it makes a guess that it is really an integer, and that’s what gets put into the test database.
The fix is to manually modify your migration scripts anywhere you have a decimal to look like:
def self.up
create_table :events do |t|
t.string :name
t.decimal :budget, :precision => 10, :scale => 2
t.timestamps
end
end
Right after I write this, I’m going to dive in and should be at least filing a bug on it.
FWIW, this has all been documentation here:
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#M001150
Thanks, but what that shows is that the default MySQL Decimal is (10,0) which was known. The problem is that when you run the db:prepare it copies over the schema from dev (which would be decimal (10,0)) and creates it in test as a BigInt(10). That’s the “bug”.