Can you create a “temporary” model in a Rails migration?

I have a Rails 2 project that has many, many relationships through a connection table. Let me name tables A, B, and ABJ, where ABJ has the properties a_id and b_id (along with id and {created,updated}_at irrelevant to this question).

What i want to do

Unfortunately, this connection was created incorrectly from the very beginning and should have been just one-to-many (A has_many B's, B belongs to_A). So I created a reconfiguration that reassigns B directly to A. Basically it goes: 1) add_column a_id to B, 2) for each ABJ, put abj.a.id in abj.b.a_id, 3) drop_table: abj. It works great.

I also created a “reverse” operation in a downward migration, to return, if I need (1) create_table abj, 2) for each B, create a new abj such as abj.a_id = b.a_id and abj. b_id = b.id, 3) remove_column a_id from B). This works fine too.

Problem

Along with “reassociation,” this relationship to one-many is the expectation that the unused ABJ pool resource will disappear, i.e. remove model, controller, tests, etc. The problem is that if I need to go back, working with downstream migration will not work, because in step 2 (for each B create a new abj) there will no longer be class ABJ < ActiveRecord::Base , since I deleted the model.

So, is there a way to make a “temporary” model within the framework of migration just for the sake of managing data in the database? Or do you simply require that the person performing the migration must make sure that this model exists before it is launched? Since if the downward migration fails in step 2, then step 1 has already created the abj table, and then you will have to manually delete it or comment on the code of step 1 during the migration process before starting it again (then uncomment it later).

I wonder if there is any good solution for this.

+4
source share
2 answers

You can define the model during the migration process. Just put the definition of barebones at the top of your migration:

 class Pancake < ActiveRecord::Base; end 

In the case when you drop the table, you need to be careful that you do not call methods on Pancake when the pancake table does not exist.

+5
source

Either go with TomL advice, or go with manual SQL (if you're using MySQL):

 UPDATE B, ABJ SET B.a_id = ABJ.a_id WHERE B.id = ABJ.b_id; 

Other RDBMS allow you to use a similar, more natural syntax using JOIN.

+1
source

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


All Articles