Migrating Data - Not Just Schema, Rails

Migrating DATA - not just schema, Rails

Best practice is: don't use models in migrations. Migrations change the way AR maps, so do not use them at all. Do it all with SQL. This way it will always work.

This:

User.all.each do |user|
user.applied_at = user.partner_application_at
user.save
end

I would do like this

update "UPDATE users SET applied_at=partner_application_at"

Can you just change Rails Schema without Migrations?

Doing database transformations without using migrations is as easy as running rails db which will start the CLI for your database and typing the SQL. But then you have to repeat those steps across the test/development/production databases and make sure any other developers working on the project also perform those steps on their local databases.

This is a really error prone process and actually solving the problem with migrations is probably a lot less insurmountable than you think.

What's the best way to go about this?

The best solution to ignorance is knowledge.

ActiveRecord migrations are just a Domain Specific Language (DSL) to create SQL queries and a mechanism to run migrations against different databases and keep tabs on which migrations have been run through a metadata table in the database.

Even if you can't express whatever query you are trying to perform through the DSL you can still use any arbitrary SQL string.

Rails DB in production change: better to reload schema or to alter the table?

The whole point of migrations is that it provides a DSL that makes it easier to perform database transformations in a repeatible way across all your environments so that you maintain parity and being able to actually test the steps in development/test greatly reduces the risk of mishaps due to simple human error.

Use the migrations Luke.

rails db:schema:load is only intended to be used when you're setting up a database up from scratch. This would be for example if you're setting a new machine up for development or during testing/CI to ensure a blank slate. Your users probably won't appreciate if you wipe their data.

Rails migration: only for schema change or also for updating data?

The short version is, since migrations are only for schema changes, you wouldn't want to use them to change actual data in the database.

The main issue is that your data-manipulating migration(s) might be ignored by other developers if they load the DB structuring using either rake db:schema:load or rake db:reset. Both of which merely load the latest version of the structure using the schema.rb file and do not touch the migrations.

As Nikita Singh also noted in the comments, I too would say the best method of changing row data is to implement a simple rake task that can be run as needed, independent of the migration structure. Or, for a first time installation, the seed.rb file is perfect to load initial system data.

Hope that rambling helps.

Update

Found some documentation in some "official" sources:

  • Rails Guide for Migrations - Using Models in your Migrations. This section gives a description of a scenario in which data-manipulation in the migration files can cause problems for other developers.
  • Rails Guide for Migrations - Migrations and Seed Data. Same document as above, doesn't really explain why it is bad to put seed or data manipulation in the migration, merely says to put all that in the seed.rd file.
  • This SO answer. This person basically says the same thing I wrote above, except they provide a quote from the book Agile Web Development with Rails (3rd edition), partially written by David Heinemeier Hansson, creator of Rails. I won't copy the quote, as you can read it in that post, but I believe it gives you a better idea of why seed or data manipulation in migrations might be considered a bad practice.

When I run a schema migration before a data migration, with ActiveRecord, data does not properly update in DB

You're assuming after the first migration runs (change_column :users, :status, :string, default: User::Status::ACTIVE) you can still fetch the old values from the status column which is not the case. When you change the type of that column to string all the integer values are invalid so I suspect your database just changes all the invalid values to be "0" instead.

If I was told to make this change to an application that is heavily used in production, I would be roll out this change in a few separate pull requests/migrations. I'd create a whole new separate column, iterate through all the users, set the value of the new column depending on what the value in the old column is, and then delete the old column. This is a much safer way to make this change.

Data not getting stored in table rails

it seems that the problem you have is not with the table itself. you just forget to add :status to your permitted parameters.

maybe you have something like this in your controller

private
def funding_params
params.require(:funding).permit(:describe_activity, :type_of_activity..., :status)
end

just add :status there to be permitted



Related Topics



Leave a reply



Submit