arsm800
arsm800

Reputation: 61

Ruby & Rails - Seeding Data With Associations from a CSV

I'm new to Ruby & Rails and I am trying to seed a rails database with data from two CSV files and create an association between them. Here is what I have so far:

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

migrations:

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: 20160603210529) 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

I am able to complete all migrations and seed the "cities" part of the seed file. But when I seed "skyscrapers", I get the following error:

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/ruby-2.2.3@global/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)

In seeds.rb, Line 42 refers to "s.city = city" and line 29 refers to "csv.each do |row|". Originally I thought there might have been a conflict between city from the foreign key and a row in the tables also named "city", so I changed to the row heading in each table to "city_name" (these used to be just "city"). However, I get the same error. When I comment out line 42 (s.city = city), everything migrates and seeds, but there is no association.

Thank you in advance for your feedback.

Upvotes: 2

Views: 1491

Answers (1)

amaksr
amaksr

Reputation: 7745

Try to add "id" primary key column to "cities" table (actually, it is a good practice to have "id" on all your tables), and then change line 42 to:

s.city_id = city.id

Upvotes: 2

Related Questions