Csv import error through smartercsv gem - ruby-on-rails

I have this csv structure
"CATEGORY";"NAME";"AGE"
"Red";"John";"34"
When I import the file through smarter_csv gem I get this hash
{:"\"CATEGORY\""=>"\"Red\"", :"\"NAME\""=>"\"John\"", :"\"AGE\""=>"\"34\""}
The code I use is the following
options = {:col_sep => ";",:row_sep => :auto, :quote_char => "\x00"}
SmarterCSV.process(save_folder, options) do |array|
Item.create(array.first)
end
What puzzles me is the \" that is added in each item of the hash. I have used this same method before without issues and I don't understand what is going wrong, but the expected hash should be plan text with no backslash and additional quotes.
As a note, is I don't use the ";quote_char => "\x00"" option I get a malformed csv error.

This works out of the box, but the quote_char you chose was incorrect; it should be '"', which is the default setting.
require 'smarter_csv'
SmarterCSV::VERSION
=> "1.2.3"
data = SmarterCSV.process('/tmp/test.csv', {:col_sep => ";"})
=> [{:category=>"Red", :name=>"John", :age=>34}]
# or like this:
data = SmarterCSV.process('/tmp/test.csv', {
:col_sep => ";",:row_sep => :auto, :quote_char => '"'
})
=> [{:category=>"Red", :name=>"John", :age=>34}]

Related

Changing the currency format for product prices within Spree

I'm upgrading spree to from spree 1.0 to 1.3 and get stuck with the new currency options.
I want to render prices as: '€ 100' but instead get '€100'. How do I get a space between the unit and the value?
Note: Changing the locale file doesn't work, since it uses the money gem.
There are a bunch of ways to do this. The easiest would probably be to re-register the Euro currency with a different symbol.
Put the following in an initializer:
# encoding: utf-8
Money::Currency.register({
:priority => 1,
:iso_code => "EUR",
:iso_numeric => "978",
:name => "Euro",
:symbol => "€ ",
:subunit => "Cent",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
A rails console now reports:
> Spree::Money.new(100, currency: 'EUR')
=> € 100.00
I did the following in my config/initializers/spree.rb to inject a different symbol:
Money::Currency.table[:chf].merge!(symbol: 'CHF ')
This way the currencies aren't going to mix up.
Thanks a lot.
In my case, used the following to change the symbol generated by the to_html method, in case anyone has the same problem.
# encoding: utf-8
Money::Currency.register({
:priority => 1,
:iso_code => "CLP",
:iso_numeric => "152",
:name => "Chilean Peso",
:symbol => "$",
:subunit => "Peso",
:subunit_to_unit => 1,
:separator => ",",
:delimiter => ".",
html_entity: "$"
})
I solved the problem with the following in an initializer, e.g. config/initializers/currency_formatting.rb:
# Display prices with a space between symbol and number:
Spree::Money.default_formatting_rules[:symbol_before_without_space] = false
This hooks into the formatting rules found in Spree::Money, which can control all the formatting Options of the Money Gem, including the one placing a space between the symbol and the number. This has the advantage over the other solutions presented here that it works with all currencies at once.
Okay, this was pretty easy. As of gem version money(6.16.0).
In Spree intializer spree.rb Recommended way:
Spree.config do |config|
...
...
# Below is deprecated
Spree::Money.default_formatting_rules[:symbol_before_without_space] = false
# Instead try this
Spree::Money.default_formatting_rules[:format] = '%u %n'
end

uploading csv file to sqlite

I am trying to upload my csv data to my sqlite table, this is my code:
require 'csv'
CSV.open('history.csv', 'r') do |row|
HistoryYear.create(:year => row[1], :first => row[2], :second => row[3], :third => row[4], :regular_season_champ => row[5])
end
I am receiving an error message, NoMethodError: undefined method '[]' for #<CSV:0x3c1fe18>. I am a new to Rails and programming in general and cannot seem to find the answer.
You need to use CSV.foreach(file...) instead
You can do something like:
require 'csv'
CSV.foreach('history.csv') do |row|
HistoryYear.create(:year => row[1], :first => row[2], :second => row[3], :third => row[4], :regular_season_champ => row[5])
end
Check out http://www.ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html
Also don't forget that arrays (the rows in this case) are 0 indexed i.e. the first element of the row is row[0].

Convert CSV to Array?

Any ideas on how to convert this CSV into a ruby array using vim?
Starting CSV:
Year,Make,Model
1997,Ford,E350
2000,Mercury,Cougar
Desired Array:
car_info = [
{'Year' => '1997', 'Make' => 'Ford', 'Model' => 'E350'},
{'Year' => '2000', 'Make' => 'Mercury', 'Model' => 'Cougar'},
]
I have > 2000 entries like the CSV above, and I'd love a way to quickly re-format it for use in my Rails app. I'd like to use vim, but I'm open to other options too.
FasterCSV.read("path/to/file.csv", :headers => true).map do |row|
{ "Year" => row[0], "Make" => row[1], "Model" => row[2] }
end
PS: Install faster_csv gem
In vim, you can use global search and replace with a regular expression:
:g/\(.*\),\(.*\),\(.*\)/s//{'Year' => '\1', 'Make' => '\2', 'Model' => '\3'}/g
Then edit the first and last lines of the resulting file accordingly.

Error parsing CSV with FasterCSV gem (MalformedCSVError)

FasterCSV is raising MalformedCSVError (Illegal Quoting) in this line:
|0150|1161623|Medicamentos e genericos "EPP".|1423|PB|
This is the code:
FasterCSV.foreach(path_to_file, :col_sep => '|') do |row|
...
end
Any ideas?
tks!!
There is also an option quote_char which defaults to ", try changing it to something, which you don't expect in your data. You might try nil but I have never tried that.
FasterCSV.foreach(path_to_file, :col_sep => '|', :quote_char => "|") do |row|
...
end

Get In That DB! Parsing CSV Using Ruby

I have a CSV file formatted just like this:
name,color,tasty,qty
apple,red,true,3
orange,orange,false,4
pear,greenish-yellowish,true,1
As you can see, each column in the Ruby OO world represents a mix of types -- string, string, boolean, int.
Now, ultimately, I want to parse each line in the file, determine the appropriate type, and insert that row into a database via a Rails migration. For ex:
Fruit.create(:name => 'apple', :color => 'red', :tasty => true, :qty => 3)
Help!
For Ruby 1.8:
require 'fastercsv'
FasterCSV.parse(my_string, :headers => true) do |row|
Fruit.create!(
:name => row['name'],
:color => row['color'],
:tasty => row['tasty'] == 'true',
:qty => row['qty].to_i
)
end
For Ruby 1.9, just rename FasterCSV to CSV and fastercsv to csv:
require 'csv'
CSV.parse(my_string, :headers => true) do |row|
# same as ruby-1.8
end

Resources