FasterCSV - illegal quoting error - thought it was correct?

Discussion in 'Ruby' started by Gabriel Saravia, Oct 27, 2010.

  1. 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, , abc123, UserRole1
    Olivia, Davis, , abc123, User Role2
    Alexander, Thomas, , 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

    --
    Posted via http://www.ruby-forum.com/.
     
    Gabriel Saravia, Oct 27, 2010
    #1
    1. Advertising

  2. On Oct 27, 2010, at 5:58 PM, Gabriel Saravia wrote:

    > 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, , abc123, UserRole1
    > Olivia, Davis, , abc123, User Role2
    > Alexander, Thomas, , 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:

    >> require "rubygems"

    =3D> true
    >> require "faster_csv"

    =3D> true
    >> FCSV.parse('a, "b, c"')

    FasterCSV::MalformedCSVError: Illegal quoting on line 1.
    ...
    >> FCSV.parse('a,"b, c"')

    =3D> [["a", "b, c"]]

    I hope that helps.

    James Edward Gray II
     
    James Edward Gray II, Oct 28, 2010
    #2
    1. Advertising

  3. On Wed, 27 Oct 2010 19:13:33 -0500, James Edward Gray II
    <> wrote in
    <>:

    >On Oct 27, 2010, at 5:58 PM, Gabriel Saravia wrote:
    >
    >> 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, , abc123, UserRole1
    >> Olivia, Davis, , abc123, User Role2
    >> Alexander, Thomas, , 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.
    >>
    >> 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:


    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,,abc123,UserRole1
    Olivia,Davis,,abc123,User Role2
    Alexander,Thomas,,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.

    --
    Charles Calvert | Software Design/Development
    Celtic Wolf, Inc. | Project Management
    http://www.celticwolf.com/ | Technical Writing
    (703) 580-0210 | Research
     
    Charles Calvert, Oct 28, 2010
    #3
  4. 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

    --
    Posted via http://www.ruby-forum.com/.
     
    Gabriel Saravia, Oct 28, 2010
    #4
  5. Re: FasterCSV

    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!

    --
    Posted via http://www.ruby-forum.com/.
     
    Francisca Munhoz, Nov 15, 2010
    #5
  6. Re: FasterCSV

    On Nov 14, 2010, at 10:48 PM, Francisca Munhoz wrote:

    > 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
    http://AgileConsultingLLC.com/
    http://GaslightSoftware.com/
     
    Rob Biedenharn, Nov 15, 2010
    #6
  7. Re: FasterCSV

    On Nov 14, 2010, at 9:48 PM, Francisca Munhoz wrote:

    > 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] }

    > end
    >
    > end


    Hope that helps.

    James Edward Gray II
     
    James Edward Gray II, Nov 16, 2010
    #7
  8. Thanks guys I really appreciate your help, both solutions work
    perfectly!

    Best regards

    Francisca

    --
    Posted via http://www.ruby-forum.com/.
     
    Francisca Munhoz, Nov 17, 2010
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. joon
    Replies:
    1
    Views:
    525
    Roedy Green
    Jul 8, 2003
  2. Dan

    correct or not correct?

    Dan, Oct 2, 2003, in forum: HTML
    Replies:
    7
    Views:
    451
  3. Ian Kelly
    Replies:
    0
    Views:
    780
    Ian Kelly
    Jan 4, 2011
  4. Junkone

    fastercsv error

    Junkone, Dec 7, 2007, in forum: Ruby
    Replies:
    3
    Views:
    144
    James Gray
    Dec 7, 2007
  5. Glenn

    Error using FasterCSV

    Glenn, Mar 15, 2008, in forum: Ruby
    Replies:
    4
    Views:
    163
    Alex Young
    Mar 20, 2008
Loading...

Share This Page