2016-05-13 23 views
0

试图CSV记录上传到城市模型数据库,收到错误UnknownAttributeError CSV

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) 

上传观点

<%= form_tag upload_path, multipart: true do %> 
    <%= file_field_tag :file %> 
    <%= submit_tag "import" %> 
<% end %> 

路线:

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 
+0

看到这个...可有人请解释为什么头必须是一个符号?谢谢 – daveasdf

回答

0

首先,ActiveRecord::UnknownAttributeError如果fieldCity模型的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"}] 

符号有什么特别之处?

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

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

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

更多信息http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html#HeaderConverters

+0

好的,谢谢!但事实是,在我添加header_converters :: symbol选项之前,City实例为csv /数据库转换返回nil,并且/或者给我一个UnknownAtrributeError,我忘记了。当我添加符号选项时,它神奇地工作。 – daveasdf

+0

以前,我试着给模型添加一个def init和一个attr_accessor,这也导致了相同的错误。但你可以从模式中看到,我在那里有'国家',并且我相应地排列了csv ...... row [1]是'Canada'。符号选项必须以某种方式将csv与适当的模型对齐,无论属性如何,为什么我不知道。 – daveasdf

+0

我也尝试#City.create!({ #名称=>行[0], #国家=>行[1], #general_info1 =>行[2], #})当我加入 的definit attr_accessors无济于事 – daveasdf

相关问题