Show:
Migrate Legacy Data
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 legacy_development: 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 end
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' end
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 = Post.new new_post.id = self.id new_post.title = self.title new_post.text = self.text new_post.author = "#{self.first_name self.lastname}".strip new_post end end
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 if new_post.save puts "Post with id: #{new_post.id} is created." else puts "Post with id: #{new_post.id} errors: #{new_post.errors.full_messages.join(", ")}\n" end end end end
So the final step is to run rake task: bundle exec rake legacy:migrate_posts
I hope that this helps you 🙂