Ruby&Rails - 使用CSV中的关联播种数据

问题描述:

我是Ruby新手& Rails,我试图从两个CSV文件中导入数据并创建它们之间的关联。以下是我迄今为止:Ruby&Rails - 使用CSV中的关联播种数据

seeds.rb

require "csv" 

City.destroy_all 
Skyscraper.destroy_all 

csv_text = File.read(Rails.root.join("public", "cities.csv")) 
csv = CSV.parse(csv_text, :headers => true) 
csv.each do |row| 
    c = City.new 
    c.city_name = row["city_name"] 
    c.country = row["country"] 
    c.save 
    puts "#{c.city_name}, #{c.country} saved" 
end 

csv_text = File.read(Rails.root.join("public", "skyscrapers.csv")).encode!("UTF-8", "binary", invalid: :replace, undef: :replace, replace: "?") 
csv = CSV.parse(csv_text, :headers => true, :encoding => "iso-8859-1:utf-8") 
csv.each do |row| 
    s = Skyscraper.new 
    s.rank = row["rank"] 
    s.name = row["name"] 
    s.city_name = row["city_name"] 
    s.country = row["country"] 
    s.heightM = row["heightM"] 
    s.heightF = row["heightF"] 
    s.floors = row["floors"] 
    s.completedYr = row["completedYr"] 
    s.materials = row["materials"] 
    s.use = row["use"] 
    city = City.find_by(city_name: row["city_name"]) 
    s.city = city 
    s.save 
    puts "#{s.rank}, #{s.name}, #{s.city_name}, #{s.country}, #{s.heightM}, #{s.heightF}, #{s.floors}, #{s.completedYr}, #{s.materials}, #{s.use} saved" 
end 

迁移:

class CreateCities < ActiveRecord::Migration 
    def change 
    create_table :cities do |t| 
     t.string :city_name 
     t.string :country 
    end 
    end 
end 


    class CreateSkyscrapers < ActiveRecord::Migration 
    def change 
    create_table :skyscrapers do |t| 
     t.integer :rank 
     t.string :name 
     t.string :city_name 
     t.string :country 
     t.integer :heightM 
     t.integer :heightF 
     t.integer :floors 
     t.integer :completedYr 
     t.string :materials 
     t.string :use 
     t.references :city, index: true, foreign_key: true 
    end 
    end 
end 

schema.rb

ActiveRecord::Schema.define(version:529) do 

    # These are extensions that must be enabled in order to support this database 
    enable_extension "plpgsql" 

    create_table "cities", force: :cascade do |t| 
    t.string "city_name" 
    t.string "country" 
    end 

    create_table "skyscrapers", force: :cascade do |t| 
    t.integer "rank" 
    t.string "name" 
    t.string "city_name" 
    t.string "country" 
    t.integer "heightM" 
    t.integer "heightF" 
    t.integer "floors" 
    t.integer "completedYr" 
    t.string "materials" 
    t.string "use" 
    t.integer "city_id" 
    end 

    add_index "skyscrapers", ["city_id"], name: "index_skyscrapers_on_city_id", using: :btree 

    add_foreign_key "skyscrapers", "cities" 
end 

我能够完成所有的迁移和种子种子文件的“城市”部分。但是,当我种子“摩天大楼”,我得到以下错误:

NoMethodError: undefined method `city=' for #<Skyscraper:0x007fa6ec913be8> 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activemodel-4.2.6/lib/active_model/attribute_methods.rb:433:in `method_missing' 
/Users/AndrewSM/wdi/Projects/skyscrapers/db/seeds.rb:42:in `block in <top (required)>' 
/Users/AndrewSM/wdi/Projects/skyscrapers/db/seeds.rb:29:in `<top (required)>' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `load' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `block in load' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `load' 
/Users/AndrewSM/.rvm/gems/[email protected]/gems/railties-4.2.6/lib/rails/engine.rb:547:in `load_seed' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activerecord-4.2.6/lib/active_record/tasks/database_tasks.rb:250:in `load_seed' 
/Users/AndrewSM/.rvm/gems/ruby-2.2.3/gems/activerecord-4.2.6/lib/active_record/railties/databases.rake:183:in `block (2 levels) in <top (required)>' 
Tasks: TOP => db:seed 
(See full trace by running task with --trace) 

在seeds.rb,42号线是指“s.city =城市”和第29行是指“csv.each做|行| ”。原本我以为城市与外界之间可能存在冲突,而城市与城市之间也存在冲突,因此我将每个表格中的行标题更改为“city_name”(以前只是“城市” )。但是,我得到了同样的错误。当我评论第42行(城市=城市)时,一切都会迁移并种下,但没有任何关联。

非常感谢您的反馈。

尝试添加“id”主键列“城市”表(实际上,这是一个很好的做法,有“身份证”上的所有表),然后更改42行:

s.city_id = city.id 
+0

我创建了一个向城市表添加主键的迁移,但是当我运行迁移时,出现错误: '''PG :: DuplicateColumn:错误:关系“城市”的列“id”已存在 :ALTER TABLE“cities”ADD“id”serial primary key''' 听起来像“城市”中的主键已经存在。但是,当我做0个新的迁移和种子,我得到一个“未定义的方法city_id”错误。 – arsm800

+0

Oof。我还需要在我的模型中声明“belongs_to”和“has_many”。现在它播种正确。 – arsm800