Activerecord 找不到使用 CSV 信息创建的记录

发布于 2024-11-27 03:54:41 字数 5989 浏览 6 评论 0原文

当我从 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 "[email protected]" 
=> nil     # Should return record created through the CSV file

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

如有任何帮助,我们将不胜感激。如果重要的话,我使用 Rails 3.1rc5。

-

使用 rows.to_hash 输出更新

根据要求,调试 rows.to_hash 的输出:

{:email=>"[email protected]", :first_name=>"First", :last_name=>"Last"}
{:email=>"[email protected]", :first_name=>"Matching", :last_name=>"Name"}
{:email=>"[email protected]", :first_name=>"asd", :last_name=>"asd"}

来自控制台的另一个示例,这进一步加深了我的困惑:

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

-

使用 SQL 更新输出

Record.find_by_email Record.find(14).email 生成的 SQL:

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" = '[email protected]' LIMIT 1

-

尝试 SQLite 控制台

sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = '[email protected]' LIMIT 1;
# This one should have returned the CSV record, but it returns nothing
sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = '[email protected]' LIMIT 1;
5|2|match|this|[email protected]|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|[email protected]|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|[email protected]|2011-07-29 19:43:23.843188|2011-07-29 19:43:23.843188
18||Matching|Name|[email protected]|2011-07-29 19:43:23.849001|2011-07-29 19:43:23.849001
19||asd|asd|[email protected]|2011-07-29 19:43:23.852037|2011-07-29 19:43:23.852037

为了更好地衡量,测试 CSV 文件:

email,first name,last name
[email protected],First,Last
[email protected],Matching,Name
[email protected],asd,asd

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 "[email protected]" 
=> nil     # Should return record created through the CSV file

> Record.create :email => "[email protected]"
> Record.find_by_email "[email protected]"
=> <Record id: 4, email: "[email protected]">
> Record.find_all_by_email "[email protected]"
=> [<Record id: 4, email: "[email protected]">]    # 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=>"[email protected]", :first_name=>"First", :last_name=>"Last"}
{:email=>"[email protected]", :first_name=>"Matching", :last_name=>"Name"}
{:email=>"[email protected]", :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: "[email protected]", created_at: "2011-07-29 18:03:25", updated_at: "2011-07-29 18:03:25">
> Record.find(14).email
=> "[email protected]"
> 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)  SELECT "records".* FROM "records" WHERE "records"."id" = ? LIMIT 1  [["id", 14]]
Record Load (0.3ms)  SELECT "records".* FROM "records" WHERE "records"."email" = '[email protected]' LIMIT 1

-

Trying out the SQLite console

sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = '[email protected]' LIMIT 1;
# This one should have returned the CSV record, but it returns nothing
sqlite> SELECT "records".* FROM "records" WHERE "records"."email" = '[email protected]' LIMIT 1;
5|2|match|this|[email protected]|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|[email protected]|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|[email protected]|2011-07-29 19:43:23.843188|2011-07-29 19:43:23.843188
18||Matching|Name|[email protected]|2011-07-29 19:43:23.849001|2011-07-29 19:43:23.849001
19||asd|asd|[email protected]|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
[email protected],First,Last
[email protected],Matching,Name
[email protected],asd,asd

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱娆 2024-12-04 03:54:41

这是你的问题。从 Record 模型中删除所有 attr_* 行。默认情况下,所有 ActiveRecord 数据库字段均可访问。通过添加 attr 字段,您可以有效地覆盖默认的 Rails 访问器,这就是为什么一切都表现得很奇怪。

值得学习的教训:当您认为模型中“没有什么有趣的”时……要非常怀疑:)祝您好运。删除这些线应该可以解决所有问题。

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.

与他有关 2024-12-04 03:54:41

结果发现是编码问题。

电子邮件、名字和姓氏被作为 blob 扔进 SQLite,我猜这会导致一两个问题。添加 :encoding => 'u' 作为 CSV.foreach 的选项修复了所有问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文