Skip to content

Instantly share code, notes, and snippets.

@nacengineer
Last active August 29, 2015 14:16
Show Gist options
  • Save nacengineer/1c6362d54df79db61c74 to your computer and use it in GitHub Desktop.
Save nacengineer/1c6362d54df79db61c74 to your computer and use it in GitHub Desktop.
Move from one Database style to Postgres

Rails 3.1+ can handle Multiple Connections

Create model to handle the old connection. For this example we've pivoted to the new database and will be connecting to the old database

Create an database setting in your database.yml

For the purposes of this example we're going to call it OldModel

Copy your current models to a new subdirectory in /app/models/

Add a namespace equal to the new subdirectory for each model file you moved and have them inherit from the model in /app/models that you created for the connection.

# For this example its */app/models/old_model.rb*
# i.e. new subdir in /app/model/old_model

# the namespace would be OldModel

class OldMode:SomeClass < OldModel
...
end

Note we're just moving attributes so technically the rest of the old class can be deleted. We just need the ability to read the database backed accessors. But your mileage may vary. Also you may need to disable the before_create filters on your class if skipping validations won't save it. (I had this issue with a before_create filter)

save(validate: false) 

Now we need a rake task

namespace :temp_migration_tasks do

  desc "Migrate Old Model"
  task pull_from_old: :environment do
    # should be pluralized version of name, i.e. table names
    to_move = %w(model1 model2 model3)
    to_move.each do |table|
      move_table table
    end
  end

  def move_table(table_name)
    old_const = Object.const_get("OldNet::#{table_name.singularize.titleize.split.join}")
    new_const = Object.const_get(table_name.singularize.titleize.split.join)

    # only needed if you'll be running more than once
    # new_const.delete_all 

    puts "Starting #{old_const.to_s} to #{new_const.to_s}"
    old_const.all.each do |object|
      o = new_const.new object.attributes
      if o.save
        puts "#{new_const} #{o.id} saved!"
      else
        # You could add your handle failed save code here
        puts "error with #{o.id} writing errors to file"
        puts o.errors.full_messages
      end
    end
    puts "B == A #{(old_const.count - new_const.count).zero?}"
    puts "Done"
    
    # only needed if you'll be running more than once
    # ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
  end
  
end

Also if you have tables in your database you may need to create classes that will allow you to transfer that information too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment