NothingToSeeHere
NothingToSeeHere

Reputation: 2363

Iterating Through Rows when importing Gsheet Worksheets Via Ruby Gem gets "no implicit conversion of String into Integer" error

I'm using the "google_drive" gem to access a Google Sheet worksheet and I've been able to access and print the worksheet, so the API connection is fine.

However, I'm trying to build a method that iterates through every row and find or creates a user based on that. I've tried these two options:


def import
      session = GoogleDrive::Session.from_service_account_key("credspath")
      spreadsheet  = session.spreadsheet_by_title("My Worksheet Title")
      worksheet  = spreadsheet.worksheets.first
      worksheet.rows.each do |row|
        customer = Customer.find_by(email: row['email'])
        if customer.blank?
           customer = Customer.new(email: row['email'] )
           puts "New Customer #{customer.email} "
        end
      end
    end

and this


def import
      session = GoogleDrive::Session.from_service_account_key("credspath")
      spreadsheet  = session.spreadsheet_by_title("My Worksheet Title")
      worksheet  = spreadsheet.worksheets.first
      CSV.foreach(worksheet, headers: true, encoding:"iso-8859-1:utf-8") do |row|
        customer = Customer.find_by(email: row['email'])
        if customer.blank?
           customer = Customer.new(email: row['email'] )
           puts "New Customer #{customer.email} "
        end
      end
    end

I'm getting the error: "no implicit conversion of String into Integer" for the line that the iteration starts on...

How can I create from this API connection WITHOUT exporting to CSV?

Upvotes: 0

Views: 356

Answers (1)

Kache
Kache

Reputation: 16727

Reducing your first example to a minimal "cell read", you have:

worksheet = spreadsheet.worksheets.first
worksheet.rows.each do |row|
  row['email']
end

The README from google-drive-ruby has a cells and rows access example like this:

ws = session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg").worksheets[0]
p ws.rows  #==> [["fuga", ""], ["foo", "bar]]

It's pretty clear that the #rows method returns Arrays, not Hashs. What you're doing is:

row = ["abcd", "xyz"]
row['email'] # will raise TypeError: no implicit conversion of String into Integer

google-drive-ruby is not loading a "table structure" of headers and rows -- it just has cells of data in a 2D table.

You need to either just access by index: row[0]

Or process the table into structured data yourself:

sheet_header, *sheet_body = sheet.rows
structured_rows = sheet_body.map do |row|
  sheet_header.zip(row).to_h # construct the hash-per-row you wanted
end

Upvotes: 4

Related Questions