How to create a reversible rail migration assistant?

I need to execute very similar sql statements (possibly with one parameter besides the table name), across multiple tables in a rails application. As a result, I get many similar migrations, for example:

class DoSomeSQLOnUser < ActiveRecord::Migration def up execute('some long sql that alters the user.field1') execute('some long sql that alters the user.field2') end def down execute('some sql that undoes the changes') end end 

Then I have the same for customers, sales, etc.

I would like to extend ActiveRecord::Migration so that I can do this instead:

 class DoSomeSQLOnUser < ActiveRecord::Migration def change do_custom_thing_on :users, :field1 do_custom_thing_on :users, :field2 end end 

How can i do this? I think I know how to do this when operations are split up and down, for example:

 class DoSomeSQLOnUser < ActiveRecord::Migration def up do_custom_thing_on :users, :field1 do_custom_thing_on :users, :field2 end def down undo_custom_thing_on :users, :field1 undo_custom_thing_on :users, :field2 end end 

But doing it so that the change is "reversible" eluded me.

+4
source share
4 answers

This is not like the official way to do this, so you probably need to open the ActiveRecord::Migration::CommandRecorder and write a new method and its inverted version.

Find the class definition in activerecord / lib / active_record / migration / command_recorder.rb .

+2
source

Not sure if you need to do anything else, but at least you should add the inverse_custom_thing method for ActiveRecord :: Migration :: CommandRecorder

+1
source

In Rails 4, there is a reversible helper method that you can use as follows:

 def change do_custom_thing_on :users, :field1 do_custom_thing_on :users, :field2 end def do_custom_thing_on(table, field) reversible do |dir| dir.up { execute "some long sql to alter #{field} on #{table}"} dir.down { execute "some long sql to undo #{field} on #{table}"} end end 
+1
source

The main purpose of the change method that he adds is to rename the columns, but not delete. The change method “knows” how to do the opposite when migration is canceled. Therefore, if you want to do something that is not deleted, just do it in the change method, it seems to me that ActiveRecord will change it itself.

You can get more detailed information from the official documentation.

0
source

Source: https://habr.com/ru/post/1485025/


All Articles