I have seen a lot of talk regarding ActiveRecord Migrations and whether or not they should be used to change data within your application, some people saying yes some saying no. My question is if you are not using Migrations to do this then what are you using? Just another script that you write?
I am after suggestitions on alternative ways and why they might be a better idea than just using migrations.
-
One problem comes if you use the provided
rake db:reset
and
rake db:schema:load
tasks, which use
schema.rb
as the basis for setting up your database. So no data gets loaded and you're stuck.In Agile Web Development with Rails, Third Edition, which you should get (if the Ruby book is the "Pickaxe" book, should this be the "Hammock" book, btw?) if you haven't done so already, DHH says:
...migrations aren’t really meant to carry seed data. They’re too temporal in nature to do that reliably. Migrations are here to bring you from one version of the schema to the next, not to create a fresh schema from scratch—we have the db/schema.rb file for that.
So, as soon as you actually get going with a real application, people won’t be running your early migrations when they set up the application. They’ll start from whatever version is stored in db/schema.rb and ignore all those previous migrations. This means that any data created by the migrations never make it into the database, so you can’t rely on it.
There are many alternative ways to have more permanent seed data. The easiest is probably just to create a new file in db/seed.rb, which contains those Product.create calls that’ll do the setup. This file can then be called after rake db:schema:load creates the initial schema.
-
a lot of times, migrations are the best fit and cannot be replaced with a separate script. Imagine the following scenario: the application is already in use with live data; the code column contains a code in the form "name-zip_code" (yeah I know it's ugly, but it happens), and you want to split that into two columns, 'name' and 'zip_code', while getting rid of the 'code' column.
def self.up add_column :companies, :zip_code, :integer add_column :companies, :name, :string Company.reset_column_information Company.find(:all).each do |company| name, zip_code = company.code.split('-') company.update_attributes(:name => name, :zip_code => zip_code) end remove_column :companies, :code end
in this case, the code column cannot be removed before the data is transfered to the name and zip code columns.
-
When I need to modify some data in the databse, I will create a Rake task that runs some library function to do the work. This way, the data manipulation will be repeatable and if required, can be run from a migration as well.
0 comments:
Post a Comment