Переход от двух строковых переменных да / нет к одной логической переменной в рельсах? - PullRequest
0 голосов
/ 15 марта 2019

Вопрос касается миграции базы данных rails.

Текущая база данных содержит две записи для предположительно логической переменной, как показано в схеме базы данных:

create_table "table_name", force: :cascade do |t|
    ... 

    t.string "yes_boolvar"
    t.string "no_boolvar"
    ...

end

Мне нужно преобразовать еев одну логическую переменную следующим образом:

    t.boolean "boolvar"

Я подумал о переименовании 'yes_boolvar', изменении его типа со строкового на логическое значение, а затем об удалении столбца 'no_boolvar' на основе некоторых показаний, например, следующего:

 t.rename :yes_boolvar,
          :boolvar
 t.change :boolvar,
          :boolean
 t.remove :no_boolvar

Однако при копировании значения переменной будет учитываться только значение истинности 'yes_ *', а не 'no_ *'.Есть ли способ успешно перенести var, чтобы учитывались истинные (или нулевые) значения обоих переменных.

Ответы [ 3 ]

0 голосов
/ 15 марта 2019

Я рекомендую вам справиться с 3 миграциями. Для начала создайте миграцию, добавив boolean: :boolvar

class AddBoolvarToTableName < ActiveRecord::Migration
  def up
    add_column :table, :boolvar, :boolean
  end

  def down
    remove_column :table, :boolvar  
  end
end

После этого создайте новую миграцию для обработки данных:

class RepopulateBooleanValues < ActiveRecord::Migration[5.0]
  def change
    YourClass.all.each do |record|
      # put the logic here like:
      record.boolvar = record.yes_boolvar == 'true' 
      # or 
      record.boolvar = record.not_boolvar == 'false'
      # I'am not sure whats the content of yes_boolvar and not_boolvar, elaborate the logic here
      record.save
    end
  end
end

Чтобы закончить, просто создайте новую миграцию, удалив yes_boolvar и no_boolvar.

0 голосов
/ 15 марта 2019

Это примерно такая миграция, которую я бы написал (я не запускал код, но он должен работать):

# This ensures the migration to work
# regardless the customizations on your original model
class TempModel < ActiveRecord::Base
  self.table_name = 'table_name'
end

class MyMigration < ActiveRecord::Migration[5.0]
  def up
    add_column :table_name, :boolvar, :boolean

    TempModel.reset_column_information
    TempModel.find_each do |record|
      # Decide some logic here about how to migrate values from yes_boolvar
      # and no_boolvar columns to boolvar column
      boolvar_value = record.yes_boolvar || !record.no_boolvar
      record.update_column :boolvar, boolvar_value
    end

     remove_column :table_name, :yes_boolvar
     remove_column :table_name, :no_boolvar
  end

  def down
    add_column :table_name, :yes_boolvar, :string
    add_column :table_name, :no_boolvar, :string

    TempModel.reset_column_information
    TempModel.find_each do |record|
      # Decide some logic here about how to handle yes_boolvar
      # and no_boolvar values
      record.update_columns yes_boolvar: record.boolvar,
                            no_boolvar: !record.boolvar
    end

    remove_column :table_name, :boolvar
  end
end
0 голосов
/ 15 марта 2019

Это зависит от вашего приложения.

Если никто не может обновить эти значения (т. Е. Это не поле в профиле пользователя), то вы можете:

  1. сделать дамп базы данных
  2. запустите миграцию
  3. выполнить код, который заполнит boolvar

Другим решением является перенос данных в 3 этапа:

  1. первая миграция переименовывает столбец
  2. вторая миграция переносит данные
  3. третья миграция удаляет no_boolvar столбец

Полагаю, можно объединить первые два действия в одну миграцию (но я предпочитаю их разделять).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...