CSV In Ruby - Doubt

Asked

Viewed 714 times

1

Good afternoon guys, I’m having a little trouble understanding how Ruby works with csv, I need to read a file and import the data from that file into a variable

I have a file called given.txt like this

Id | Nome | Endereco

1 | Renato | Alameda das magnolias

Both separated by t

put the | to separate just to exemplify

So I created a class called parser in parse.Rb

require 'csv'

Class Parser  

attr_reader :file

def initialize(file)
 begin
   @file = File.open(file) 
 rescue Exception => exception
   raise Exception, "Failed to load file#{exception}" 
 end
end

def parse
 CSV.foreach(@file, {headers: true, header_converters: :symbol, col_sep: '\t', }) do |row|
    p row[:id]
    p row[:nome]
    ...
end 

end

but when I introduce the Parser class, I call parse method I cannot return the columns the idea is to play the records in an array or hash to save to a database later.

Can someone give me a hint of where I’m going wrong? never had problems with Ruby but I am now in working with csv Thank you for your attention

the idea is to abstract this class to read uploaded CSV files by forms, and enter the data in the database

1 answer

0

Good night,

first thing, in this code you posted I detected two syntax errors:

  1. the keyword Class is in lowercase: class

  2. missing a end in the method parse. One to the block do and another for the purpose of defining the method.

Going straight to the problem, what happens is that the Ruby language only recognizes the escape character \t (among others) when the string is involved in double quotes (see here).

Then this code will work:

require 'csv'

class Parser  

    attr_reader :file

    def initialize(file)
     begin
       @file = File.open(file) 
     rescue Exception => exception
       raise Exception, "Failed to load file#{exception}" 
     end
    end

    def parse
     CSV.foreach(
        @file, 
        {
            headers: true, 
            header_converters: :symbol, 
            col_sep: "\t"
        }) do |row|
            next if row.empty?
            puts row[:id]
            puts row[:nome]
        end

    end 

end

parse = Parser.new(__dir__ + '/dado.txt')
parse.parse
#=> 1
#=> Renato

I took the liberty of placing a parole (next if row.empty?) to skip loop iteration when the row is empty (in your example, there is an empty row between the header and the start of the data).

I hope it helps.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.