开发者

Activerecord doesn't find record created with CSV info

When I create Records from a CSV file, Activerecord can't find them with Record#find_by. If I create a Record through the rails console, it works as expected. Here's my code for creating through CSV:

def create
  file = params[:record][:file].tempfile

  CSV.foreach file, :headers => true, :header_converters => :symbol do |row|
    Record.create row.to_hash
  end

  redirect_to records_url
end

Here are some examples from the console:

> Record.find_by_email "matching@asd.asd" 
=> nil     # Should return record created through the CSV file

> Record.create :email => "matching@asd.asd"
> Record.find_by_email "matching@asd.asd"
=> <Record id: 4, email: "matching@asd.asd">
> Record.find_all_by_email "matching@asd.asd"
=> [<Record id: 4, email: "matching@asd.asd">]    # Should return both

Any help would be appreciated. I'm on Rails 3.1rc5 if it matters.

-

Updated with rows.to_hash output

As requested, the output from debugging rows.to_hash:

{:email=>"Matching@asd.asd", :first_name=>"First", :last_name=>"Last"}
{:email=>"Notmatching@asd.asd", :first_name=>"Matching", :last_name=>"Name"}
{:email=>"asdasdasdasd@asd.asd", :first_name=>"asd", :last_name=>"asd"}

Another example from the console, which furthers my confusion:

> Record.find 14    # Record created by CSV
=> <Record id: 14, first_name: "First", last_name: "Last", email: "Matching@asd.asd", created_at: "2011-07-29 18:03:25", updated_at: "2011-07-29 18:03:25">
> Record.find(14).email
=> "Matching@asd.asd"
> Record.find_by_email Record.find(14).email
=> nil

-

Updated with SQL output

SQL generated by Record.find_by_email Record.find(14).email:

Record Load (0.3ms)  SEL开发者_JS百科ECT "records".* FROM "records" WHERE "records"."id" = ? LIMIT 1  [["id", 14]]
Record Load (0.3ms)  SELECT "records".* FROM "records" WHERE "records"."email" = 'Matching@asd.asd' LIMIT 1

-

Trying out the SQLite console

sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = 'Matching@asd.asd' LIMIT 1;
# This one should have returned the CSV record, but it returns nothing
sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = 'nomatch@asd.asd' LIMIT 1;
5|2|match|this|nomatch@asd.asd|2011-07-29 17:13:13.821972|2011-07-29 17:13:13.821972

-

Adding model code, query results, CSV input

Possibly the most exciting model known to man:

class Record < ActiveRecord::Base
  attr_accessible :email, :first_name, :last_name, :file
  attr_accessor :file
end

More results from the query:

sqlite> select * from records;
5|2|match|this|nomatch@asd.asd|2011-07-29 17:13:13.821972|2011-07-29 17:13:13.821972
9|3|first|last||2011-07-29 17:56:50.471766|2011-07-29 17:56:50.471766
10|6|first|last||2011-07-29 17:56:54.917432|2011-07-29 17:56:54.917432
17||First|Last|Matching@asd.asd|2011-07-29 19:43:23.843188|2011-07-29 19:43:23.843188
18||Matching|Name|Notmatching@asd.asd|2011-07-29 19:43:23.849001|2011-07-29 19:43:23.849001
19||asd|asd|asdasdasdasd@asd.asd|2011-07-29 19:43:23.852037|2011-07-29 19:43:23.852037

For good measure, the test CSV file:

email,first name,last name
Matching@asd.asd,First,Last
Notmatching@asd.asd,Matching,Name
asdasdasdasd@asd.asd,asd,asd


Here is your problem. Remove all attr_* lines from your Record model. All ActiveRecord database fields are accessible by default. By adding attr fields you are effectively overwriting the default Rails accessors and that's why everything is acting weird.

Lesson to learn: when you think you have "nothing interesting" in your model...be very suspicious :) Good luck. Removing those lines should fix everything.


It turned out to be an encoding problem.

The email, first name and last name were thrown into SQLite as blobs, which I guess causes a problem or two. Adding :encoding => 'u' as an option for CSV.foreach fixed everything up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜