I'm working in filling a database with a .csv file in which each row is a long code. I have a hash with the positions for each column and with that I'm creating another hash that stores the column name as the key and the value. In addition I want to create some other columns based on the ones from de csv but when trying to call de values to perform operations they return nil. However, when I call the hash it shows that none of the values are nil.
Here is a sample of the .csv: file
Here is my code:
require 'rake'
require 'csv'
namespace :import do
desc "delete old data and load data from file"
task rolcobro: :environment do
SiiPropiedad.delete_all
filename = ENV["FILE"].present? ? ENV["FILE"] : "sample.txt"
rowshash = {codigo_comuna: [0,4],
anio: [5,8],
semestre: [9,9],
aseo: [10,10],
direccion: [17,56],
manzana: [57,61],
predio: [62,66],
serie: [67,67],
cuota_trimestral: [68,80],
avaluo_total: [81,95],
avaluo_exento: [96,110],
anio_fin_exencion: [111,114],
ubicacion: [115,115],
destino: [116,117]
}
dir = "db/csv/"
filepath = File.join Rails.root, "#{dir}#{filename}"
CSV.foreach(filepath, headers: false) do |row|
texto = row[0].to_s
attributes = {"texto": texto}
rowshash.each do |key,value|
attributes[key] = texto[value[0]..value[1]]
end
#HERE THE "rol" MUST BE CREATED FROM "manzana" AND "predio". EX: IF attributes["manzana"] = "00308" AND attributes["predio"] = "00061" (AS STR) THEN attributes["rol"] should be "308-61"
attributes["rol"] = "#{attributes["manzana"].to_i}-#{attributes["predio"].to_i}"
#HERE IF IT IS " " I WANT THE FIRST MSG, ELSE (WHEN IT IS "A") THE LATER
attributes["aseo"] == " " ? "Cuota trimestral no incluye aseo" : "Cuota trimestral incluye aseo"
SiiPropiedad.find_or_create_by(attributes)
end
end
end
In all cases I get nothing for "rol" and for "aseo" the condition won't work. I'm sure I'm missing some basics. Can you help me please?
CodePudding user response:
Your hash keys are symbols, but you're using strings to add new keys and for lookup. For example, attributes["rol"] = "value"
will make a string key "rol"
.
rowshash = {
symbol: "this is a symbol",
"also symbol": "symbol again",
:"third symbol" => "another symbol",
"string" => "a string key"
}
rowshash[:symbol] # => "this is a symbol"
rowshash[:"also symbol"] # => "symbol again"
rowshash[:"third symbol"] # => "another symbol"
rowshash["string"] # => "a string key"
You can't lookup symbol keys with strings and vice versa. When you ask for a key that doesn't exist you get the default value which is nil
:
rowshash["symbol"] # => nil
rowshash["also symbol"] # => nil
rowshash["third symbol"] # => nil
rowshash[:"string"] # => nil
If you want to get a different default value, you can use default=
method on the hash itself.
rowshash.default = "new default"
rowshash["not found"] # => "new default"