Activerecord 找不到使用 CSV 信息创建的记录
当我从 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是你的问题。从
Record
模型中删除所有attr_*
行。默认情况下,所有ActiveRecord
数据库字段均可访问。通过添加 attr 字段,您可以有效地覆盖默认的 Rails 访问器,这就是为什么一切都表现得很奇怪。值得学习的教训:当您认为模型中“没有什么有趣的”时……要非常怀疑:)祝您好运。删除这些线应该可以解决所有问题。
Here is your problem. Remove all
attr_*
lines from yourRecord
model. AllActiveRecord
database fields are accessible by default. By addingattr
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.
结果发现是编码问题。
电子邮件、名字和姓氏被作为 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 forCSV.foreach
fixed everything up.