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
Capistrano 3 Execute Within a Directory
How to Alias a Class Method in Rails Model
Run Rails Commands Outside of Console
Define_Method: How to Dynamically Create Methods with Arguments
Ruby: How to Generate CSV Files That Has Excel-Friendly Encoding
Clarification on the Ruby << Operator
How to Parse Consecutive Tags with Nokogiri
Ruby: How to "Require" a File from the Current Working Dir
How to Do Advanced String Comparison in Ruby
Adding a Submit Button Image to a Rails Form
How to Assert Certain Method Is Called with Ruby Minitest Framework