Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby strings that appear the same are not equal, why?

I am importing a CSV and creating rows using ActiveRecord. The CSV is:

first_name,middle_name,last_name,degrees,email,induction_year (ie 2017),"induction_type (options: alumni, associate, faculty, honorary, student)"
John,Middle,Doe,"BA, MPH",[email protected],2017,alumni

My method to import looks something like this:

def import
  CSV.foreach(@file.path, headers: true, header_converters: lambda {|field| field.partition(" ").first }, col_sep: ',') do |row|
    member_params = row.to_hash
    Member.create!(member_params)
  end
end

But it throws ActiveModel::UnknownAttributeError: unknown attribute 'first_name' for Member. Edit: It's not a problem with Member I can create Member as you would expect with something like Member.create!(first_name: 'test')

Open up a pry and I get this feedback:

[1] pry(#<InducteesUpload>)> member_params
=> {"first_name"=>"John",
"middle_name"=>"Middle",
"last_name"=>"Doe",
"degrees"=>"BA, MPH",
"email"=>"[email protected]",
"induction_year"=>"2017",
"induction_type"=>"alumni"}
[2] pry(#<InducteesUpload>)> member_params.keys.first == "first_name"
 => false
[3] pry(#<InducteesUpload>)> member_params.keys.first.encoding
=> #<Encoding:UTF-8>

Adding more:

[1] pry(#<InducteesUpload>)> member_params.keys
=> ["first_name",
  "middle_name",
  "last_name",
  "degrees",
  "email",
  "induction_year",
  "induction_type"]

[2] pry(#<InducteesUpload>)> member_params["first_name"] = "test"
=> "test"
[3] pry(#<InducteesUpload>)> member_params
=> {"first_name"=>"John",
 "middle_name"=>"Middle",
 "last_name"=>"Doe",
 "degrees"=>"BA, MPH",
 "email"=>"[email protected]",
 "induction_year"=>"2017",
 "induction_type"=>"alumni",
 "first_name"=>"test"}

It's not a problem with Member as can you see with the above weirdness. But will post if it you really want.

So problem is revealed here:

[6] pry(#<InducteesUpload>)> member_params.keys.first.bytes
=> [239, 187, 191, 102, 105, 114, 115, 116, 95, 110, 97, 109, 101]
[7] pry(#<InducteesUpload>)> "first_name".bytes
=> [102, 105, 114, 115, 116, 95, 110, 97, 109, 101]
like image 751
esteban Avatar asked Oct 24 '25 04:10

esteban


1 Answers

I'm betting on unicode magic. Compare member_params.keys.first.bytes and "first_name".bytes. You're likely to find a difference.

Unicode has a lot of symbols that look alike, but are not equal to each other.

like image 182
Sergio Tulentsev Avatar answered Oct 25 '25 17:10

Sergio Tulentsev