Re: migrations ignoring record changes

Vitaly Kushner
Mon, 07 Jan 2008 23:32:07 -0000

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''" ? :)

On Jan 7, 8:37 pm, Josh <jjkie...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> 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?
>
> On Jan 7, 12:30 pm, Josh
<jjkie...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > 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.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe@googlegroups.com