2

I am trying to do the following in IRB:

file = CSV.read('branches.csv', headers:true) 
file.each do |branch|
  Branch.create(attributes:branch.to_hash)
end

branches.csv contains one header entitled business_name which should map onto the attribute for Branch of the same name, but I see the error:

ActiveRecord::UnknownAttributeError: unknown attribute 'business_name' for Branch.

Strangely, doing Branch.create(business_name:'test') works just fine with no issues.

Update:

enter image description here

enter image description here

I think this has something to do with the encoding of the text in the UTF-8 CSV produced by Excel as suggested in the comments below. Not sure if this IRB gives any clues... but our header title business_name != "business_name"

2.3.3 :348 > file = CSV.read('x.csv', headers:true)
#<CSV::Table mode:col_or_row row_count:165>
2.3.3 :349 > puts file.first.to_hash.first.first
business_name
2.3.3 :350 > file = CSV.read('x.csv', headers:true)
#<CSV::Table mode:col_or_row row_count:165>
2.3.3 :351 > puts file.first.to_hash.first.first == "business_name"
false
Abram
  • 39,950
  • 26
  • 134
  • 184
  • What exactly does `branch.to_hash` return? What is the encoding of the keys in the hash, what encoding do you use in Ruby? Does the `business_name` key in the hash match `business_name` form your example when converted to its character's hex values (the `_` might look the same, but might be actually a different character)? How does you `Branch` class look like, is any of the methods involved (`initialize`, `create` or `new`) overridden? – spickermann Apr 29 '17 at 06:19
  • `branch.to_hash` gives me exactly what you'd expect, something like `{"business_name"=>"Aylesbury"}`... I even tried symbolizing keys but that didn't help. I have no overridden methods on the `Branch` model. I saved the file from Excel using UTF-8 CSV and in database.yml all databases set to `encoding: utf8` – Abram Apr 30 '17 at 19:56
  • Added possibly a clue in my updated question. – Abram Apr 30 '17 at 20:10
  • I am not sure if I would trust Excel and the pretty old CSV library to handle UTF8 correctly. Currently my best guess is that your have either a encode issue somewhere (ASCII or Win-xxxx instead of UTF8) or someone used a special type underscore to troll you. I would copy the strings into hex editors and investigate each char and each byte. Given what bytes define the underscore char in both versions should help to identify the encodings. Similar question that might be interesting to you: https://stackoverflow.com/questions/7047944 or https://stackoverflow.com/questions/5053216 – spickermann May 01 '17 at 07:28
  • The crazy thing is that I manually typed those header titles in by hand, so I'm really not sure what's up. For now I could only find one way around this, and that was removing the header columns and putting them in manually using `write_headers:true, headers: ['business_name']`, etc – Abram May 01 '17 at 13:49
  • See for a possible answer to this. – Lucas Haley Apr 11 '18 at 12:48

1 Answers1

2

Just skip the attributes: part. It is not needed at all, because branch.to_hash already returns exactly the format you describe in your last sentence.

file = CSV.read('branches.csv', headers:true) 
file.each { |branch| Branch.create(branch.to_hash) }
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • Thanks for the suggestion but unfortunately I see the exact same error after removing `attributes:` – Abram Apr 29 '17 at 00:54