我通过ActiveAdmin(http://activeadmin.info/)上传了超过100个食谱,其中包含以下属性:
class CreateRecipes < ActiveRecord::Migration
def change
create_table :recipes do |t|
t.string :title
t.string :description
t.string :ingredients
t.string :position
t.timestamps
end
end
end
我需要将字符串中的位置更改为整数。我能够通过以下方式实现这一目标:
change_column :table_name, :column_name, :integer
stackoverflow:Rails migration for change column
问题在于我不知道怎么回去并用一个位置重新分配所有食谱(现在它是一个整数)。我基本上想从0开始一直到100。如果我创建一个新的配方,它会自动获得101的位置值。
有没有办法在不退回并单独更改每个食谱的情况下执行此操作?
答案 0 :(得分:1)
听起来您最初要将:position
设置为:id
。你可以通过rails控制台这样做:
recipes = CreateRecipes.all
recipes.each do |recipe|
recipe.position = recipe.id
end
然后,对于新的食谱,在您的模型(create_recipes.rb
)中,您可以添加:
after_initialize :default_values
...
def default_values
self.position ||= id
end
顺便说一下,这是处理默认值或初始值的一种很好的干净方法。有关详细信息,请参阅此优秀帖子How can I set default values in ActiveRecord?。
答案 1 :(得分:0)
您可以将转化作为迁移本身的一部分自动运行。添加代码以将现有记录中的值转换为迁移。使用self.up和self.down为迁移的方向提供适当的转换代码:
class ChangeRecipePositionToInteger < ActiveRecord::Migration
def self.up
position_values = Hash[ Recipe.all.map{|r| [r.id, r.position]}]
change_column :recipes, :position, :integer
position_values.each_pair do |id, position_value|
recipe = Recipe.find( id )
recipe.position = position_value.to_i
recipe.save
end
end
def self.down
position_values = Hash[ Recipe.all.map{|r| [r.id, r.position]}]
change_column :recipes, :position, :string
position_values.each_pari do |id, position_value|
recipe = Recipe.find( id )
recipe.position = position_value.to_s
recipe.save
end
end
end