Reputation: 61
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
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