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