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
我创建了一个向城市表添加主键的迁移,但是当我运行迁移时,出现错误: '''PG :: DuplicateColumn:错误:关系“城市”的列“id”已存在 :ALTER TABLE“cities”ADD“id”serial primary key''' 听起来像“城市”中的主键已经存在。但是,当我做0个新的迁移和种子,我得到一个“未定义的方法city_id”错误。 – arsm800
Oof。我还需要在我的模型中声明“belongs_to”和“has_many”。现在它播种正确。 – arsm800