2011-07-29 30 views
0

當我從CSV文件創建記錄時,Activerecord無法通過Record#find_by找到它們。如果我通過導軌控制檯創建一個記錄,它按預期工作。這是我通過CSV創建代碼:Activerecord未找到使用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 
+1

請在循環內調試'row.to_hash'包含的內容。 'logger.info row.to_hash'。 – Casper

+0

@Casper:我用'logger.info row.to_hash'和另一個例子的結果編輯了問題。希望能幫助到你。 – Nathan

+1

嗯。添加更多調試到控制檯:'ActiveRecord :: Base.logger = Logger.new(STDOUT)'。它爲'Record.find_by_email Record.find(14).email'生成了什麼SQL? – Casper

回答

0

原來是一個編碼問題。

電子郵件,名字和姓氏作爲斑點被扔進SQLite,我猜想會導致一兩個問題。作爲CSV.foreach的選項添加:encoding => 'u'修復了一切。

+0

它使用':encoding =>'UTF-8''可以更好地工作。 – Nathan

1

這是你的問題。從您的Record型號中刪除所有attr_*行。所有ActiveRecord數據庫字段默認都是可訪問的。通過添加attr字段,您將有效覆蓋默認的Rails訪問器,這就是爲什麼一切都會變得怪異。

經驗教訓:當你認爲自己的模型中「沒有什麼有趣」時......非常可疑:)祝你好運。刪除這些行應該修復一切。

+0

啊,只要它那麼簡單。我繼續進行測試,並使用穩定的3.0.9應用程序和空白的3.1.0rc5應用程序進行測試。使用'Record.find_by_email'在3.0.9應用程序上按預期工作。所以看起來我的問題在於候選版本。再次感謝幫助我完成這一切。關閉我去的bug跟蹤器。 – Nathan