Home > Net >  Hash[key] in Ruby returns nil but hash has no nil values
Hash[key] in Ruby returns nil but hash has no nil values

Time:07-20

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"

https://rubyapi.org/3.1/o/hash

  • Related