Skip to content

Latest commit

 

History

History
128 lines (98 loc) · 4.42 KB

File metadata and controls

128 lines (98 loc) · 4.42 KB

Importing Legacy Tabluar Data e.g. from cvs Files always sucks. With these Table Importer you are able to import any legacy Data and map it easily to any (e.g.ActiveRecord) Objects

  • Nested Objects

  • Supports Active Record Associations (has_one, belongs_to, has_many

  • Easy converting of Data with Procs

  • get your Data as nested Array in rows and columns

  • build a dictionary to map your data to your Classes

    {"ClassName"=>attributes}
    

where attributes is a hash of of objects attributes and its corresponding columns

attributes = {:attribute=>:col_1}
  • you can use number or letters eg. :col1, :col_1, :col_A, :colB, :col_AB, :col_aa etc.

  • for pre processing data use array with a lambda as last element

    :attribute => [:co_l,col_2,lambda{|col1,col2| col1 +" " +col2 }]
  • use constant values

    :attribute=> "My Value"
    
  • for associations user Hashes

    :association => {:attribute=>:col1}
  • Build the Mapper by passing the dictonary

    mapper = TableImporter::Mapper.new(dictonary)
    
  • Build the Importer by passing the data and the mapper

    importer = TableImporter:Importer.new(data,mapper)
    
  • build

    result = importer.build
    
  • you get your result as nested Array [FirstRow [First First Level Object,Second First Level Object],Second Row […] ]

The Objects are only build not saved so you can post process them before saving.

Assume you have the follwoing Tabluar Data (e.g. from a CVS File with CSV.read(“your_file.csv”))

data=
[
 # we have only one row in this example
 ["Bob","Marley","First Avenue 23","12345","New York","Ann","Admins","School","Friends","Private"]
]

And you have the follwoing simple Data Structure

Class Contact < ActiveRecord::Base
  # first_name  String (column1)
  # last_name   String (column2)
  # full_name   String (column1 column2)
  has_many :tags
  belongs_to :user
  has_one :address
end

Class Tag < ActiveRecord::Base
  #tagging String (column 8, 9 and 10)
  belongs_to :contact
end

Class User < ActiveRecord::Base
  # name String  (column 6)
  has_many :contacts
  has_one :group
end

Class Group
  # name String  (column 7)   
end

Class Address
 # street    String  (column3)
 # number    Integer (RegEx Number Part of column3)
 # zip       String  (column4)
 # city      String  (column5)
 # country   String  ('USA' constant for the import)
 belongs_to :contact
end

You can build your Data as follows

  • first we setup our dictonary hash

    dictonary = {"Contact" =>{:first_name=>:col_1,:last_name=>:col_2,:full_name=>[:col_1,:col_2,lambda{|f,l| "#{v} #{l}"}],
                             # has_many associations you have three tags here
                             :tags=>{:tagging => [:col_8,:col_9,:col_10]},
                             # nested belongs_to
                             :user => {:name=>:col_6,:group=>{:name=>:col_7}},
                             # has_one
                             :address => {:street=>[:col_3,lambda{|s| s[/(.*?) ([\d]+)/,1]}],
                                         :number=>[:col_3,lambda{|s| s[/(.*?) ([\d]+)/,2]}],
                                         :zip=>:col_4,:city=>:col_5,:country=>"USA"
                                       }
                             }
                 }
    
  • now we create a new mapper Object, passing the dictonary

    mapper = TableImporter::Mapper.new(dictonary)
    
  • and an Importer Object passing the data

    importer = TableImporter:Importer.new(data,mapper)
    result = importer.build
    
  • it should return the processed objects

    => [[#<Contact first_name="Bob",last_name="Marley",full_name="Bob Marley",
                   tags=[#<Tag tagging="Private">,#<Tag tagging="School">,#<Tag tagging="Friends">],
                   address=#<Address street="First Avenue",number=23,zip="12345",city="New York",country="USA">
                   user =#<User name="Ann",group=#<Group name="Admin"> >    ]]

Copyright © 2010 by Manuel Kniep. All rights reserved.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.