Recently we were working on a Rails project where we needed to import data from legacy database. In the next few steps I will describe how we did it.

In database.yml we specified information for interaction with legacy data.

# config/database.yml
  host: localhost
  database: legacy

In models directory, we added a legacy directory to which we will later add all legacy models. But first we created a Legacy::Base class which will inherit from ActiveRecord::Base. In it, we established a connection with a legacy database. This way we isolate our connection to the legacy database and all our legacy models will inherit from Legacy::Base.

# app/models/legacy/base.rb
class Legacy::Base < ActiveRecord::Base
  establish_connection :legacy_development
  self.abstract_class = true

So now we will create a legacy model and we will specify a table name from legacy database.

# app/models/legacy/post.rb
class Legacy::Post < Legacy::Base
  self.table_name = 'posts'

Once we have done this it is the time to check if legacy posts are available. So we can run bundle exec rails console in our terminal and get all legacy posts: Legacy::Post.all

In our case we added a new method which helps us to migrate data. In it we will match legacy data with our new model attributes.

 class Legacy::Post < Legacy::Base
   self.table_name = 'posts'

   def to_new_model
     new_post        =     =
     new_post.title  = self.title
     new_post.text   = self.text = "#{self.first_name self.lastname}".strip


We used a rake task to migrate data. In it we are going to loop through all legacy posts and use to_new_model method to set the data, if the data is valid they will be saved otherwise we will catch an error.

  # lib/tasks/migrate_posts.rb
  namespace :legacy do
    task migrate_posts: :environment do

      Legacy::Post.all.each do |post|
        new_post = post.to_new_model

          puts "Post with id: #{} is created."
          puts "Post with id: #{} errors: #{new_post.errors.full_messages.join(", ")}\n"

So the final step is to run rake task: bundle exec rake legacy:migrate_posts

I hope that this helps you :)

Tags: ruby, rails, legacy, rake task


comments powered by Disqus