Search code examples
mysqlruby-on-railspostgresqlrails-migrationsupdate-all

Rails migration: update_all with dynamic code is possible?


I'd like to add a new field in a table.

My new "secret_code" field in my User model should be equal to Digest::SHA1.hexdigest([Time.now, rand].join)[1..12].

What I'm trying to do is generate a migration that would add the field to the table and also populate my existing users with a (sort of) unique "secret_code".

class AddSecretCodeToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :secret_code, :string
    User.update_all ["secret_code =?", Digest::SHA1.hexdigest([Time.now, rand].join)[1..12]]
  end

  def self.down
    remove_column :users, :secret_code
  end
end

The problem is that this migration populate all the existing users with the same secret code!

One solution would be NOT to use update_all and run a loop to fetch every user and send an update to each one, but in this case my migration would be extremely slow.

Is there a way to send a "unique" random value to an update_all method?

Thanks, Augusto


Solution

  • Try changing it to Digest::SHA1.hexdigest([Time.now, rand].to_s) but personally I'd create a rake task to the above as it's not really a migration.

    Your rake task would do

    User.all.each do |u|
      u.update_attribute(:secret_code, Digest::SHA1.hexdigest([Time.now, rand].to_s))
    end
    

    However, for your migration I'd also add t.string :secret_code, :default => Digest::SHA1.hexdigest([Time.now, rand].to_s) to the attribute so that it is added on newly created records.