从两个字符串yes / no变量迁移到rails中的单个布尔变量?

问题描述 投票:0回答:3

问题是关于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,以便考虑两个变量的真值(或零值)。

ruby-on-rails database-migration ruby-on-rails-5.1
3个回答
0
投票

这取决于您的应用程序。

如果没有人可以更新这些值(即它不是用户配置文件中的字段),那么您可以:

  1. 进行数据库转储
  2. 运行您的迁移
  3. 执行一个填充boolvar的代码

另一种解决方案是以3个步骤迁移数据:

  1. 第一个迁移重命名列
  2. 第二次迁移迁移数据
  3. 第三次迁移删除了no_boolvar

我想可以将前两个动作合并为一个迁移(但我更喜欢将它们分开)。


0
投票

我建议你处理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_boolvarno_boolvar


0
投票

这大致是我写的迁移(我没有运行代码,但它应该工作):

# 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
© www.soinside.com 2019 - 2024. All rights reserved.