Reputation: 951
I have over 100 recipes uploaded through ActiveAdmin (http://activeadmin.info/) in with the following attributes:
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
I needed to change position from a string to an integer. I was able to do this with the following:
change_column :table_name, :column_name, :integer
stackoverflow: Rails migration for change column
The issue is that I do not know how to go back and reassign all the recipes with a position (now that it's an integer). I basically want to start at 0 and go all the way to 100. And if i create a new recipe, it automatically has the position value of 101.
Is there a way to do this without going back and individually changing each recipe?
Upvotes: 1
Views: 1291
Reputation: 506
You can have the conversion run automatically as part of the migration itself. Add the code to convert the values in the existing records into the migration. Use self.up and self.down to have the appropriate conversion code for that direction of the migration:
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
Upvotes: 0
Reputation: 2639
It sounds like you want to set :position
to :id
initially. You could do that through the rails console like so:
recipes = CreateRecipes.all
recipes.each do |recipe|
recipe.position = recipe.id
end
Then, for new recipes, in your model (create_recipes.rb
), you could add:
after_initialize :default_values
...
def default_values
self.position ||= id
end
Incidentally, this is a nice clean way to handle default or initial values in general. For more information, see this excellent post How can I set default values in ActiveRecord?.
Upvotes: 1