My work is pretty simple. I have to migrate a bulk of data into the specified tables, so that the data does show up at the front-end. The data is provided through the Excel sheet and I have to convert it into a CSV file with $
as a field delimiter.
And later I have to write a method in an Active Record Model to perform the migration.
def self.discipline_and_speciality_migration_21Jan14
filename = "#{RAILS_ROOT}/config/discipline_and_speciality_migration_220114.csv"
file=File.new(filename,"r")
while (line = file.gets)
columns = line.split("$")
location = Location.find_by_name(columns[2].to_s.chomp.strip)
if location.blank?
location = Location.create!(:name => columns[2].to_s.chomp.strip,:short_name => columns[2].to_s.slice(0,11) , :status => "Active")
end
discipline = Discipline.find_by_name_and_location_id(columns[0].to_s.chomp.strip,location.id)
if discipline.blank?
discipline = Discipline.create!(:name=>columns[0].to_s.chomp.strip,:status=>'Active',:location_id => location.id,:code=> columns[1].to_s.chomp.strip)
else
discipline.update_attributes(:location_id => location.id)
end
speciality = Speciality.find_by_name_and_location_id(columns[3].to_s.chomp.strip)
if speciality.blank?
speciality = Speciality.create!(:name => columns[3].to_s.chomp.strip,:status=>'Active',:location_id => location.id,:code=> columns[4].to_s.chomp.strip,:discipline_id => discipline.id)
else
speciality.update_attributes(:location_id => location.id,:discipline_id => discipline.id)
end
end
end
I have no Issues with the code. I am just wondering is there any better approach to do this. Is CSV the only way? Notable modifications in the code are also welcomed.
2 Answers 2
You can use first_or_initialize
and first_or_create!
to skip the if...else
statementes.
location = Location.where(name: 'New York').first_or_create! do |loc|
loc.short_name = 'NY'
loc.status = 'Active'
end
discipline = Discipline.where(name: 'Name', location_id: location.id).first_or_initialize
discipline.assign_attributes code: 'code', status: 'Active'
discipline.save!
speciality = Speciality.where(name: 'Name', location_id: location.id).first_or_initialize
speciality.assign_attributes code: 'code', discipline_id, discipline.id
speciality.save!
Using an array to hold your variables is hard to maintain and to read. You can assign the fields to real variable names:
while (line = file.gets)
discipline_name, _, location_name, speciality_name, code =
line.split("$").map(&:to_s).map(&:chomp).(&:strip)
location = Location.find_by_name(location_name)
if location.blank?
location = Location.create!(:name => location_name,:short_name => columns[2].to_s.slice(0,11) , :status => "Active")
end
discipline = Discipline.find_by_name_and_location_id(discipline_name,location.id)
if discipline.blank?
discipline = Discipline.create!(:name=>discipline_name,:status=>'Active',:location_id => location.id,:code=> columns[1].to_s.chomp.strip)
else
discipline.update_attributes(:location_id => location.id)
end
speciality = Speciality.find_by_name_and_location_id(speciality_name)
if speciality.blank?
speciality = Speciality.create!(:name => speciality_name,:status=>'Active',:location_id => location.id,:code=> code,:discipline_id => discipline.id)
else
speciality.update_attributes(:location_id => location.id,:discipline_id => discipline.id)
end
end