Seven years ago in 2012 I spoke at RubyConf China 2012. It was a technical talk on how to become a better developer, if you're interested…
Update: You might also want to check out
So a few days ago we started seeing the following errors on our Jenkins builds (swapped with fictional model and attribute names):
NoMethodError: undefined method `attack_power=' for #<Ironman:0x00000008525d20>
attack_power is a new attribute we recently added to the
Ironman ActiveRecord model.
I was baffled, as the table column is clearly there but ActiveRecord couldn’t see it.
This weird behaviour is confirmed by debugging the model:
Ironman # => Ironman(id: integer, created_at: datetime, updated_at: datetime) Ironman.column_names # => ["id", "created_at", "updated_at"]
And by debugging the schema:
ActiveRecord::Base.connection.structure_dump # => "CREATE TABLE `ironmans` (\n `id` int(11) NOT NULL AUTO_INCREMENT,\n `created_at` datetime NOT NULL,\n `updated_at` datetime NOT NULL,\n `attack_power` int(11) NOT NULL,\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;\n\n"
So apparently somehow ActiveRecord ate our
After some struggling and head-scratching, finally I’ve discovered that during the migration if we call the
Ironman class, then any subsequent attribute changes to the class will not be recognised by ActiveRecord.
It turns out, because we run our test suites by invoking rake tasks:
And we manually reset our database beforehand too within the same
ActiveRecord will cache its attributes as soon as a model class (
Ironman) is called during the migration.
The fix? Simple! Simply use another process to run the database reset:
system 'rake db:reset'