# Data Migrations using Model Classes vs. SQL

**URL:** <https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474>\
**Category:** Rails\
**Created:** [September 13, 2007, 2:23am UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474 "2007-09-13T02:23:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Geoffrey\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@Geoffrey\_W](https://www.ruby-forum.com/u/Geoffrey_W)\
**Post date:** [September 13, 2007, 2:23am UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474/1 "2007-09-13T02:23:39Z")

</div>

I’m working on my first official migration that inserts data rather  
than changing the structure of the database; there’s some data we’d  
like to be present in any database, so it seems sensible to put it in  
a migration.

However, I’m realizing that it’s not all that simple. The obvious way  
to do a data migration is to use the model class.  
Imagine that I have an organization with a mandatory name and an  
optional description:

e.g. create\_table :organizations do |t|  
t.column :name, :string, :null =\> false  
t.column :description, :string  
end

So, for instance, if I want an organization called “Us”, i might do:

def self.up  
Organization.new( :name =\> ‘Us’ ).save!  
end

This works ok for now, but I’m realizing that it couples the migration  
to the ‘current’ version of the model class. For instance, if I later  
make description mandatory, and validate that (validates\_presence\_of),  
this migration will cease to work. That means that a new developer  
won’t be able to get the database by running the migration, because  
the migration will complain that the organization does not have a  
description.

So – does that mean I should do all data migrations using SQL  
statements? How are other people approaching this?

- Geoffrey

---

<div class="post-metadata">

**Author:** ![Geoffrey\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@Geoffrey\_W](https://www.ruby-forum.com/u/Geoffrey_W)\
**Post date:** [September 13, 2007, 3:25am UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474/2 "2007-09-13T03:25:43Z")

</div>

I think there’s a recipe In the “Rails Recipes” book for this

---

<div class="post-metadata">

**Author:** ![Geoffrey\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@Geoffrey\_W](https://www.ruby-forum.com/u/Geoffrey_W)\
**Post date:** [September 13, 2007, 4:36am UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474/3 "2007-09-13T04:36:52Z")

</div>

On 9/12/07, Geoffrey W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> e.g. create\_table :organizations do |t|  
> t.column :name, :string, :null =\> false  
> t.column :description, :string  
> end
> 
> So, for instance, if I want an organization called “Us”, i might do:
> 
> def self.up  
> Organization.new( :name =\> ‘Us’ ).save!  
> end

You can simplify that to Organization.create :name =\> ‘Us’

> statements? How are other people approaching this?  
> One thing you can do is to pre-declare your model class at the top of  
> your migration file:

class Organization \< ActiveRecord::Base  
end

class MyMigration \< ActiveRecord::Migration  
def self.up  
…

Since the Organization class exists, Rails won’t try to load your  
model file. Without the model file, you don’t get validations,  
associations, etc.

---

<div class="post-metadata">

**Author:** ![Geoffrey\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@Geoffrey\_W](https://www.ruby-forum.com/u/Geoffrey_W)\
**Post date:** [September 13, 2007, 5:06am UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474/4 "2007-09-13T05:06:53Z")

</div>

Two important comments on this…

On Sep 12, 2007, at 10:36 PM, Bob S. wrote:

> > Imagine that I have an organization with a mandatory name and an  
> > Organization.new( :name =\> ‘Us’ ).save!  
> > end
> 
> You can simplify that to Organization.create :name =\> ‘Us’

If you create or change the table, then you must call  
Organization.reset\_column\_information before trying to do anything  
through the model.

> > 
> 
> ```
> def self.up
> ...
> 
> ```
> 
> Since the Organization class exists, Rails won’t try to load your  
> model file. Without the model file, you don’t get validations,  
> associations, etc.

Actually, you want to declare a minimal version of your model  
_INSIDE_ the migration class like so:

class MyMigration \< ActiveRecord::Migration  
class Organization \< ActiveRecord::Base  
end

```
 def self.up
      ...
 end

```

end

This way, you can have several migrations that use “the” model. You  
can even define little helper methods that might only make sense  
during the migration.

It’s nice to use ‘say’ or ‘say\_with\_time’ in the migration if you’re  
doing a lot of data shuffling so you (or the other developers) don’t  
assume that the migration is stuck.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Geoffrey\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/57b2e6/32.png) [@Geoffrey\_W](https://www.ruby-forum.com/u/Geoffrey_W)\
**Post date:** [September 13, 2007, 3:19pm UTC](https://www.ruby-forum.com/t/data-migrations-using-model-classes-vs-sql/114474/5 "2007-09-13T15:19:21Z")

</div>

On Sep 12, 9:24 pm, dailer [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I think there’s a recipe In the “Rails Recipes” book for this

Ah, so there is; just for anyone who finds this thread later, this is  
mostly the same information that’s being delivered by other people on  
this thread, so if you don’t have the book handy, just read on.
