1

We have a problem regarding a migration when we try to update some data contained in a table.

Our base model looks like this:

User

  • username
  • password

We created a first migration to add a column in the model and then update the existing rows:

add_column :users, :deleted, :boolean

User.all.each do |user|
  user.deleted = false
  user.save
end

The second migration is supposed to create a last_name column and rename the username column to first_name:

rename_column :users, :username, :first_name
add_column :users, :last_name, :string

It worked without any problem in development because the second migration was created several days after the first one (so everyone had enough time to apply the first well before the second one).

The problem we have is when we try to deploy those migrations it in staging/production to the following model:

class User < ActiveRecord::Base

  attr_accessible :first_name,
                  :last_name,
                  :password,
                  :password_confirmation,
                  ...

  ...

end

The first migration fails on the save because first_name and last_name don't exist yet although they're present in attr_accessible.

The problem persists even if we try to bypass validation.

Did you ever have this kind of issue and could you help us bypass it because we'd like to stick to full ruby code without writing any SQL?

2 Answers2

0

Use add_column :users, :deleted, :boolean, :default => false. This should replace your fragment with save method.

Grzegorz Łuszczek
  • 548
  • 1
  • 3
  • 16
  • We can do it for this example. But it's a simple example, when the logic behind the default value is more complex, we cannot set a hard coded default value, Rails must make the work itself. – kdisneur-silicon May 05 '12 at 10:04
  • Default value is always same for all new records, otherwise this isn't default. In more complex situation I would use a pure SQL. – Grzegorz Łuszczek May 05 '12 at 11:02
0

You may force ActiveRecord to reload the models information from the database in your migrations whenever required :

User.reset_column_information

When your models are not consistent enough with the former database state you may also switch to raw SQL to perform updates using the execute method :

execute 'UPDATE users SET deleted=0'
Jef
  • 5,424
  • 26
  • 28