rails 3.0 attr_encrypted существующей базы данных

#ruby-on-rails-3 #encryption

#ruby-on-rails-3 #шифрование

Вопрос:

В rails 3.0 мне нужно зашифровать существующее текстовое поле. Существует таблица memos, которая содержит текстовое поле «примечание». Я создал поле encrypted_note и добавил его в модель:

 attr_encrypted :note, :key => 'a secret key'
  

На данный момент, когда я загружаю существующую запись, «примечание» пустое. Я предполагаю, что attr_encrypted попытается расшифровать … но поле еще не зашифровано!

attr_encrypted хорошо работает для новых записей, но интересно, какая стратегия шифрования существующих записей была бы наилучшей?

Ответ №1:

Работает ли instance_variable_get('@note') или read_attribute('note') ?

Если это так, вы, вероятно, можете сделать что-то подобное в консоли Rails:

 User.all.each do |user|
  user.note = user.instance_variable_get('@note')
  user.save
end
  

Комментарии:

1. read_attribute отлично работает, спасибо!… Я попытался одновременно с заполнением encrypted_note очистить поле «примечание» в базе данных, выполнив user.write_attribute(‘примечание’,»), но я получил эту ошибку: вызван частный метод `write_attribute’… есть идеи?

Ответ №2:

Вот хитрость, позволяющая очищать незашифрованный столбец по мере заполнения зашифрованного! в модели добавить:

 before_update :clear_note

def clear_note
   if encrypted_note != nil amp;amp; read_attribute('note') != nil
     write_attribute('note','')
   end
end
  

Ответ №3:

Предполагая, что вы начинаете с вашей модели Thing с незашифрованного атрибута note .

1) Добавьте миграцию, чтобы добавить поле encrypted_note и заполнить его

   class EncryptThing < ActiveRecord::Migration
    def up
      rename_column :things, :note, :old_note
      add_column :things, :encrypted_note, :string
      # if you want to use per-attribute iv and salt:
      # add_column :things, :encrypted_note_iv, :string
      # add_column :things, :encrypted_note_salt, :string

      Thing.find_each do |t|
        t.note = t.old_note
        t.save
      end

      remove_column :things, :old_note
    end

    def down
      raise ActiveRecord::IrreversibleMigration
    end
  end
  

2) Добавьте строку в свою модель, чтобы указать зашифрованный атрибут:

     attr_encrypted :note, :key => Rails.application.config.key
    # if you want to use per-attribute iv and salt, add this to the line above:
    #   ,  :mode => :per_attribute_iv_and_salt
  

3) запустите миграцию

     rake db:migrate