Something ago I wrote about the problems which arise when using models in your Rails migrations. Meanwhile I developed a really simple solution to this problem and today I wrapped it up in to a plugin called
How to use it? Install it in your Rails application:
ruby script/plugin install
and apply it in your migration:
class DowncaseUserNames < ActiveRecord::Migration
User.find(:all).each do |user|
Look at the
README file for a more elaborate example.
So how does it work? It simply undefines the models your referring to and redefines an empty ActiveRecord class;
Object.send :remove_const, :User rescue nil
class User < ActiveRecord::Base; end
Now you are sure to have a
User model available in your migration without any validations which may make data manipulations impossible. The undefining of an already available model also ensures you don’t need to use
ActiveRecord::Base.reset_column_information before updating new fields, unless you use your model before altering the table of course.
Update: As coderrr points out you don’t need to clobber the global scope model class because a nested model works fine too. I wrongly assumed introducing a new model class in side (!) a migration class would only reopen my original model class and keep validations intact. To illustrate:
class User; def top; end; end
class User; def nested; end; end
p User.instance_methods - Object.instance_methods
["nested"] and not
["top", "nested"] as I suspected. Apparently I was bitten too hard by a problem which arose when I used an original model class to even try the above. I’ll pull the plugin because it’s pointless.. Bad me, thanks coderrr!