Activerecord не находит запись, созданную с помощью информации CSV - PullRequest
0 голосов
/ 29 июля 2011

Когда я создаю записи из файла CSV, Activerecord не может найти их с Record#find_by.Если я создаю запись через консоль rails, она работает как положено.Вот мой код для создания через 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

Вот несколько примеров из консоли:

> 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

Любая помощь будет оценена.Я на Rails 3.1rc5, если это имеет значение.

-

Обновлено с rows.to_hash output

По запросу, вывод из строк отладки.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"}

Еще один пример из консоли, который еще больше сбивает меня с толку:

> 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

-

Обновлен с выводом SQL

SQL, сгенерированный Record.find_by_email Record.find(14).email:

Record Load (0.3ms)  SELECT "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

-

Испытание консоли SQLite

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

-

Добавление кода модели, результатов запроса, CSV-ввода

Возможно, самая захватывающая модель, известная человеку:

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

Дополнительные результаты по запросу:

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

Для правильной оценки, тестовый файл CSV:

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

Ответы [ 2 ]

1 голос
/ 30 июля 2011

Вот ваша проблема. Удалите все attr_* строки из вашей Record модели. Все ActiveRecord поля базы данных доступны по умолчанию. Добавляя поля attr, вы фактически перезаписываете аксессоры Rails по умолчанию, и поэтому все действует странно.

Урок для изучения: когда вы думаете, что в вашей модели нет «ничего интересного» ... будьте очень подозрительны :) Удачи. Удаление этих строк должно исправить все.

0 голосов
/ 30 июля 2011

Оказалось, проблема с кодировкой.

Электронная почта, имя и фамилия были добавлены в SQLite в виде BLOB-объектов, которые, как мне кажется, вызывают одну или две проблемы. Добавление :encoding => 'u' в качестве опции для CSV.foreach исправило все.

...