dho dho - 1 month ago 10
Ruby Question

How to iterate over rows and print out CSV::Table values in Sinatra

I'm making a simple Sinatra app and have the following 'numbers.csv' file:

Name,Title,Phone
Ally Smith,Manager,888-552-444
Rick Jones,Director,888-552-447
Hayley Bowman,Accountant,888-552-424


The task is to print the name and phone numbers in an erb file.

I originally solved this problem with nested arrays:

get '/' do
# turns CSV into array with nested arrays
@names = CSV.read('names.csv')
# delete headers
@names.shift
erb :index
end


and an each loop:

<tr>
<th>Name</th>
<th>Number</th>
</tr>

<% @names.each do |row| %>
<tr>
<td> <%= row[0] %> </td>
<td> <%= row[2] %> </td>
<tr>
<% end %>


Now I am trying to overcome my fear of working with objects and hashes, so I am approaching the problem like this:

get '/' do
# turns CSV into object with key value pairs
@numbers = CSV.read('numbers.csv', headers:true)
erb :index
end


I know that the benefit of using a CSV::Table object with headers means that I can access the values like so:

@names[i]["Name"]
@names[i]["Phone"]


where
i
is the counter for each row, followed by the key names.

I tried writing a while loop in the erb file – fail. Also a foreach loop that I understand is as CSV method and modified my code accordingly – fail.

I'm having trouble iterating over the rows and calling the specific keys.

I'm not sure if I am using the right loops.

Any advice would be greatly appreciated.

I have been working on this for hours :(

Answer

The code is fine. As i show below:

> numbers = CSV.read('numbers.csv', headers:true)
> numbers.each do |row|
>     puts "#{row['Name']} - #{row['Phone']}"
>   end

Ally Smith - 888-552-444
Rick Jones - 888-552-447
Hayley Bowman - 888-552-424

I think your problem is your variables. you should use @numbers instead of @names in your second example:

@names[i]["Name"] # should be @numbers[i]['Name']