UnknownAttributeError csv

试图将csv记录上传到City model数据库,收到错误

ActiveRecord::UnknownAttributeError in PagesController#import unknown attribute 'country ' for City. (City.create! row.to_hash) 

CSV:

 name country general_info1 general_info2 (etc) Toronto Canada This is a test (nil) 

上传视图

     

路线:

 post '/upload' => 'pages#import' 

PagesController

 def import City.import(params[:file]) end 

城市模型

 def self.import(file) logger.info "__________________" logger.info file.inspect logger.info file.path logger.info "__________________" CSV.foreach(file.path, headers: true) do |row| City.create! row.to_hash #puts '&&&&&&&&&&&&&&&&&&&&&&&' + row[1] logger.info row.inspect end 

模式

 ActiveRecord::Schema.define(version: 20160513090837) do create_table "cities", force: :cascade do |t| t.string "name" t.string "country" t.string "general_info1" t.string "general_info2" t.integer "happiness_rating" t.integer "family_safety_rating" t.string "family_safety_info" t.integer "bike_hobby_rating" t.string "bike_hobby_info" t.integer "accountant_rating" t.integer "accountant_shortage_rating" t.string "accountant_shortage" t.integer "accountant_avg_salary" t.integer "graphic_designer_rating" t.string "graphic_designer_shortage" t.integer "graphic_designer_avg_salary" t.integer "journalist_rating" t.string "journalist_shortage" t.integer "journalist_avg_salary" t.datetime "created_at", null: false t.datetime "updated_at", null: false end end 

提前谢谢了

回答:

 CSV.foreach(file.path, {headers: true, header_converters: :symbol}) do |row| City.create!(row.to_hash) end 

首先,如果City模型create!field发生ActiveRecord::UnknownAttributeError create! 期望在cities表中存在的方法表缺席。 确保它在那里。

有人可以解释为什么标题需要成为一个符号?

在ruby中解析CSV时,通常会将数据作为Hash es的集合获取。 在下面的示例中,您可能已经注意到所有Hash es的keys都在重复,它们是String数据。 在Ruby每个String实例占用不同的内存空间。

 csv.to_a.map {|row| row.to_hash } # => [{"Year"=>"1997", "Make"=>"Ford", "Model"=>"E350", "Description"=>"ac, abs, moon", "Price"=>"3000.00"}, {"Year"=>"1999", "Make"=>"Chevy", "Model"=>"Venture \"Extended Edition\"", "Description"=>"", "Price"=>"4900.00"}, {"Year"=>"1999", "Make"=>"Chevy", "Model"=>"Venture \"Extended Edition, Very Large\"", "Description"=>nil, "Price"=>"5000.00"}, {"Year"=>"1996", "Make"=>"Jeep", "Model"=>"Grand Cherokee", "Description"=>"MUST SELL!\nair, moon roof, loaded", "Price"=>"4799.00"}] 

说字符串computer占用8 bytes 。 如果我将这个字符串定义为1000,000次,它将占用我的RAM的8MB

现在,如果你使用header_converters: :symbol ,这将调用to_sym方法,该方法现在将keys定义为symbol s。

 csv = CSV.new(body, :headers => true, :header_converters => :symbol) csv.to_a.map {|row| row.to_hash } # => [{:year=>"1997", :make=>"Ford", :model=>"E350", :description=>"ac, abs, moon", :price=>"3000.00"}, {:year=>"1999", :make=>"Chevy", :model=>"Venture \"Extended Edition\"", :description=>"", :price=>"4900.00"}, {:year=>"1999", :make=>"Chevy", :model=>"Venture \"Extended Edition, Very Large\"", :description=>nil, :price=>"5000.00"}, {:year=>"1996", :make=>"Jeep", :model=>"Grand Cherokee", :description=>"MUST SELL!\nair, moon roof, loaded", :price=>"4799.00"}] 

符号有什么特别之处?

符号具有内存效率,检索速度非常快。 如果你定义符号:computer 1000,000次,它将只占用8Bytes的内存。

这个解释如何解决我的问题?

您的CSV文件可能有数千行数据要转换为Hash 。 因此,为了使此过程更快,内存效率更高,请使用header_converters: :symbol

有关详细信息,请参阅此内容http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html#HeaderConverters