I really like the Rails 3 style migrations, i.e. one change method being smart enough to recognize if the migrations is being installed or rolled back, so I don’t have to write up and down methods mirroring each other. But I have situation that I need to skip some code when the migration is rolled back (updating counter_cache columns that I’m adding).
I looked at http://guides.rubyonrails.org/migrations.html but the examples at the end of section 5 suffer from the same problem:
class AddFuzzToProduct < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
def change
add_column :products, :fuzz, :string
Product.reset_column_information
Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
end
end
When this migration is rolled back, the update of fuzz field is unnecessary. Is there a way to prevent it?
I tried looking into Product.column_names but since Rails is smart enough to perform migration in reverse direction, the update is executed before the column is removed. Also, when change method is defined, any up or down methods seem to be ignored. Any other ideas?
In this case I think you’ll have to use
upanddownmethods as usual. Don’t worry, despite the addition ofchangein Rails 3 those methods aren’t, as far as I know, bound for the chopping block. Continue using them where necessary.Edit: Here’s an option: Override
migrate.Thoughts?