# Migrations ignoring record changes

**URL:** <https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276>\
**Category:** Rails\
**Created:** [January 7, 2008, 7:31pm UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276 "2008-01-07T19:31:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjkiesch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc79bd/32.png) [@jjkiesch](https://www.ruby-forum.com/u/jjkiesch)\
**Post date:** [January 7, 2008, 7:31pm UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276/1 "2008-01-07T19:31:51Z")

</div>

I had a users table and went back to add columns for first name and  
last name. Just so it would not cause errors, I was trying to loop  
through the existing users in the database and set the first name  
column to “First” and the last name column to “Last”

Before updating to rails 2, i was able to do something like this:

class AddFirstNameAndLastNameToUsers \< ActiveRecord::Migration  
def self.up  
add\_column :users, :first\_name, :string  
add\_column :users, :last\_name, :string

```
User.find(:all).each do |user|
  user.first_name = 'First'
  user.last_name = 'Last'
  user.save
end

```

end

def self.down  
remove\_column :users, :first\_name  
remove\_column :users, :last\_name  
end  
end

For some reason, the columns are created, but the names are never  
changed. When looking at the database, everything is still NULL. When  
calling save on the user object, I see MYSQL updates being made, but  
without the columns that were just added.

I can’t figure out why this won’t work and would greatly appreciate  
any insight.

Thanks.

---

<div class="post-metadata">

**Author:** ![jjkiesch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc79bd/32.png) [@jjkiesch](https://www.ruby-forum.com/u/jjkiesch)\
**Post date:** [January 7, 2008, 7:37pm UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276/2 "2008-01-07T19:37:42Z")

</div>

Almost immediately after posting this, I tried splitting this into two  
separate migrations. One to add/remove the columns and the one after  
that to update all of the records in the database. Running rake  
db:migrate and updating everything at once didn’t work, but running  
the migration all the way up to the version that adds the columns, and  
then re-running rake db:migrate a second time worked. So I guess the  
model is just not being reloaded once the new columns are added.

Is it possible that this is a bug, or is this the way it was meant to  
work?

---

<div class="post-metadata">

**Author:** ![jjkiesch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc79bd/32.png) [@jjkiesch](https://www.ruby-forum.com/u/jjkiesch)\
**Post date:** [January 7, 2008, 8:21pm UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276/3 "2008-01-07T20:21:11Z")

</div>

In general, you have to tell ActiveRecord that it needs to rethink the  
columns that the database has:

User.reset\_column\_information

But in this case, there’s not really a need to get the model involved.

User.update\_all([‘first\_name = ?, last\_name = ?’, “First”, “Last”])

will do the same think (and a lot faster, too!)

-Rob

On Jan 7, 2008, at 1:37 PM, Josh wrote:

> > add\_column :users, :first\_name, :string  
> > add\_column :users, :last\_name, :string

```
  User.reset_column_information

```

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

---

<div class="post-metadata">

**Author:** ![jjkiesch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc79bd/32.png) [@jjkiesch](https://www.ruby-forum.com/u/jjkiesch)\
**Post date:** [January 8, 2008, 12:32am UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276/4 "2008-01-08T00:32:58Z")

</div>

I recently had a similar problem in our project. The migrations would  
pass when running one by one, but would fail when run all in sequence  
when bootstrapping the database. Finding the problem and fixing it led  
me to discovery that we had a lot more ‘potential’ problems in our  
large number of migrations. So I came to realize the following  
principle:

You should NOT use your models in migrations.

Think about it. This migration might need to run to bootstrap an empty  
database later down the road, when the model might not even exist. or  
its fields/methods will change.  
User model is usually more stable then the rest but still.

What you should do is to define your model AGAIN in your migration  
together with all the functions and other models it might use during  
the migration.  
In your case:

class AddFirstNameAndLastNameToUsers \< ActiveRecord::Migration

# you need to copy all the member functions that you use during the

migration

# this way you don’t have to worry later when you change/remove this

modal that

# your migrations will fail. and you DON’T need new functionality in

old migration. ever. well, except _may be_ for fixing bugs 🙂

# Also you MUST define it inside the migration class or unique

module, so that it will be different from such models used in other  
migrations as all migrations are loaded together.  
class User \< ActiveRecord::Base  
end

def self.up  
add\_column :users, :first\_name, :string  
add\_column :users, :last\_name, :string

```
# ALSO make sure you use your model for the first time AFTER you

```

change its table schema  
# or call reset\_column\_information as Rob suggested.

```
User.find(:all).each do |user| # <<==== This is usually a bad

```

thing to do. If you have BIG user table and use some eager loading, it  
will load ALL into memory  
user.first\_name = ‘First’  
user.last\_name = ‘Last’  
user.save  
end  
end  
def self.down  
remove\_column :users, :first\_name  
remove\_column :users, :last\_name  
end  
end

And BTW, why don’t you just User.update\_all “first\_name=‘First’,  
last\_name=‘Last’” ? 🙂

---

<div class="post-metadata">

**Author:** ![jjkiesch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/bc79bd/32.png) [@jjkiesch](https://www.ruby-forum.com/u/jjkiesch)\
**Post date:** [January 7, 2008, 11:46pm UTC](https://www.ruby-forum.com/t/migrations-ignoring-record-changes/125276/5 "2008-01-07T23:46:11Z")

</div>

On Jan 7, 2008 2:14 PM, Rob B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> will do the same think (and a lot faster, too!)  
> I’m not sure that this is what’s going on though.

> > On Jan 7, 12:30 pm, Josh [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > Before updating to rails 2, i was able to do something like this:
> > > 
> > > class AddFirstNameAndLastNameToUsers \< ActiveRecord::Migration  
> > > def self.up  
> > > add\_column :users, :first\_name, :string  
> > > add\_column :users, :last\_name, :string  
> > > User.find(:all).each do |user|  
> > > user.first\_name = ‘First’

If AR wasn’t rereading the table definition, then that user.first\_name  
should have raised a method\_missing exception wouldn’t it.

UNLESS, his model already had defined first\_name=

On the other hand I notice that he’s using save instead of save! so we  
don’t know whether or not any validations are failing.

In any event, it should be pointed out that it’s not a good idea to  
let migrations find AR classes this way, because migrations can fail  
or worse when the model class changes.

The safe way to do this is to do something like

class AddFirstNameAndLastNameToUsers \< ActiveRecord::Migration

```
class User < ActiveRecord::Base
end
...

```

You can of course add relationship declarations and even methods if  
you need them to the user class (which will actually be  
AddFirstNameAndLastNameToUsers::User)

The point is that the behaviour of the model class is effectively  
frozen for this point in the migration stream.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)
