FasterCSV - illegal quoting error - thought it was correct?

G

Gabriel Saravia

I'm running:
rvm/gems/ruby-1.8.7-p302/gems/fastercsv-1.5.3


I have a csv file that includes many rows here's an example snippet
including the header row:

First Name, Last Name, Email, Password, Roles
Sophia, Jackson, (e-mail address removed), abc123, UserRole1
Olivia, Davis, (e-mail address removed), abc123, User Role2
Alexander, Thomas, (e-mail address removed), abc123, "UserRole1, User Role2"

my code is:

fcsv = FasterCSV.open(self.csv_file_name, "rb", {:headers => true,
:return_headers => false})
fcsv.each do |row|
user = User.new(csv_row_to_user_attributes(row))


I have no problems with any row above Alexander, each user of which only
has 1 role, UserRole1 or User Role2. But on Alexander I get an "Illegal
quoting" error.

I thought that this was the correct way to handle this situation
according to the standard. I do not want the quotes to be returned as
part of my string, i just want the string that is the user roles. One
set of quotes returns me the error illegal quoting, two sets of quotes
returns me the same error. Shouldn't three sets include the quotes as
part of the string? Well, it still returns me the same error.

What am I doing wrong? thanks.

-Gabe
 
J

James Edward Gray II

I have a csv file that includes many rows here's an example snippet
including the header row:
=20
First Name, Last Name, Email, Password, Roles
Sophia, Jackson, (e-mail address removed), abc123, UserRole1
Olivia, Davis, (e-mail address removed), abc123, User Role2
Alexander, Thomas, (e-mail address removed), abc123, "UserRole1, User = Role2"

I thought that this was the correct way to handle this situation
according to the standard. I do not want the quotes to be returned as
part of my string, i just want the string that is the user roles. One
set of quotes returns me the error illegal quoting, two sets of quotes
returns me the same error. Shouldn't three sets include the quotes as
part of the string? Well, it still returns me the same error.
=20
What am I doing wrong? thanks.

The issue is the spaces after your commas. A quoted field must begin =
with a quote, not a space. Here's an example:
FasterCSV::MalformedCSVError: Illegal quoting on line 1.
...=3D> [["a", "b, c"]]

I hope that helps.

James Edward Gray II
 
C

Charles Calvert

The issue is the spaces after your commas. A quoted field must
begin with a quote, not a space. Here's an example:

To expand on this, if you check the values returned for other rows,
you'll find that they're being returned with the leading space
included:

irb(main):004:0> row = FasterCSV.parse('a, b, c')
=> [["a", " b", " c"]]
irb(main):005:0> row[0]
=> ["a", " b", " c"]
irb(main):006:0> row[0][0].size
=> 1
irb(main):007:0> row[0][1].size
=> 2

Note the difference between the first value and the second and third
values. The latter have leading spaces.

You should eliminate the spaces so that your rows look like this:

First Name,Last Name,Email,Password,Roles
Sophia,Jackson,[email protected],abc123,UserRole1
Olivia,Davis,[email protected],abc123,User Role2
Alexander,Thomas,[email protected],abc123,"UserRole1,User Role2"

It's less easy for a human to read, but adheres to the RFC
(http://tools.ietf.org/html/rfc4180#page-2). See section 2.4.
 
G

Gabriel Saravia

Thanks! both for the answer and creating FasterCSV in the first place.

And yeah, that was the issue. I got rid of all the spaces after the
commas and now it works.

-Gabe
 
F

Francisca Munhoz

Hi I'm learning Ruby, so I have a beginners question for you:

How Can I sort attributes.values for similar order as csv_header? Just
consider that I already order by csv_header on my query but i did not
work.

@custom_csv = User.find:)all, :select=>"name, lastname, address " :eek:rder
=> "name, lastname, address")

csv_header = [name,lastname,address]

csv_string = FasterCSV.generate do |csv|

csv << csv_header

@custom_csv.each do |v|

csv << v.attributes.values

end

end

Thanks in advance!
 
R

Rob Biedenharn

Hi I'm learning Ruby, so I have a beginners question for you:

How Can I sort attributes.values for similar order as csv_header? Just
consider that I already order by csv_header on my query but i did not
work.

@custom_csv = User.find:)all, :select=>"name, lastname, address
" :eek:rder
=> "name, lastname, address")

csv_header = [name,lastname,address]

csv_string = FasterCSV.generate do |csv|

csv << csv_header

@custom_csv.each do |v|

csv << v.attributes.values

end

end

Thanks in advance!


Well, since you've already limited the attributes that ActiveRecord
will see (assuming by your syntax that User is a model derived from
ActiveRecord::Base), then v.attributes will be a hash that contains
just those three key/value pairs.

Your definition of the headers probably needs to be something like:
csv_header = %w[ name lastname address ]
but then the statement in the inner loop can be:
csv << v.attributes.values_at(*csv_header)
You can lookup the docs for Hash#values_at and the * is the "unary
unarray" operator or the "splat" which places the elements of
csv_header into the argument list separately. This is equivalent to:
csv << v.attributes.values_at("name","lastname","address")

If you have other questions that get more Rails-specific, I'd suggest
jumping over to the rails list.
http://groups.google.com/group/rubyonrails-talk?hl=en

-Rob

Rob Biedenharn
(e-mail address removed) http://AgileConsultingLLC.com/
(e-mail address removed) http://GaslightSoftware.com/
 
J

James Edward Gray II

How Can I sort attributes.values for similar order as csv_header? Just
consider that I already order by csv_header on my query but i did not
work.

@custom_csv = User.find:)all, :select=>"name, lastname, address " :eek:rder
=> "name, lastname, address")

csv_header = [name,lastname,address]

csv_string = FasterCSV.generate do |csv|

csv << csv_header

@custom_csv.each do |v|

csv << v.attributes.values

I think you can replace the above line with:

csv << csv_header.map { |h| v[h] }

Hope that helps.

James Edward Gray II
 
F

Francisca Munhoz

Thanks guys I really appreciate your help, both solutions work
perfectly!

Best regards

Francisca
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top