简体   繁体   中英

Loading data from a CSV with header in Ruby

I want to load a CSV file and create objects based on the data. The file has the following structure:

product code;product name;product price;units
RTF0145;Mixer;659;15
GTF4895;PC;9999;25

While loading the data I want to skip the first row with headers but I have a trouble using the {:headers => true} attribute, the method does nothing, no error is raised.

def Store.load_data(file, separator, headers = true)
  begin
    @items = []
    CSV.open(file, "r", {:col_sep => separator}, {:headers => headers}) do |csv|
      csv.each do |product|
        @items << Store.new(product["product code"], product["product name"], product["price"], product["units"])
      end
    end
  rescue
  end
end

I call the method like this:

Store.load_data("products.csv", ";")

If I use it without the headers argument everything works as expected:

  def Store.load_data(file, separator, headers = true)
    begin
      @items = []
      CSV.foreach(file, { :col_sep => separator }) do |row|
        @items << Store.new(row[0], row[1], row[2], row[3]) unless row[0] == "product code"
      end
    rescue
    end
  end

The signature for the CSV.open method is:

CSV.open(filename, mode = "rb", options = Hash.new)

Therefore calling it like this:

CSV.open(file, "r", { ... }, { ... }) 

...is incorrect, and Ruby should throw an exception when you do that.

The correct way to call CSV.open with a Hash is either:

CSV.open(file, "r", { :a => b, :c => d, :e => f })

Or:

CSV.open(file, "r", :a => b, :c => d, :e => f)

So, to fix your problem the solution should be to change this:

CSV.open(file, "r", { :col_sep => separator }, { :headers => headers })

To this:

CSV.open(file, "r", { :col_sep => separator, :headers => headers })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM