Невозможно назначить объект базы данных другому, проверка не прошла: класс должен существовать - PullRequest
0 голосов
/ 19 октября 2019

Я заполняю базу данных, используя два CSV файла для создания двух таблиц, continents и emissions. continents использует файл стран с демографическими данными по каждой стране, emissions использует файл выбросов CO2 с несколькими записями для каждой страны за каждый год, начиная с 1850 года. Emission должен принадлежать Continent, на основании которогострану, которую представляет каждая запись. Первая таблица относится к классу Continent на has_many и имеет каркас, построенный для MVC, а вторая таблица просто имеет модель и belongs_to класс Continents.

Я пытаюсь заполнить таблицы с помощью файла rake, сначала заполнив таблицу continents, а затем заполнив таблицу emissions, где таблица emissions имеет атрибут с именем continent_id, так что он принадлежит Continent объект. Я пытаюсь сделать это путем поиска правильного идентификатора континента с помощью

Continent.select(:id).where("Country = ?", country_temp)

Однако я получаю сообщение об ошибке Validation Failed: Continent must exist

continents.rake

require 'csv'
namespace :continents do
  desc "pull worlddata into database"
  task seed_continents: :environment do

    #drop the old table data before importing the new stuff
    Continent.destroy_all
    Emission.destroy_all

    CSV.foreach("lib/assets/Socio-Economic_Baseline_Data.csv", :headers =>false) do |row |
      puts row.inspect #just so that we know the file's being read

      #create new model instances with the data
      Continent.create!(
      Continent: row[0],
      Country: row[1].to_s,
      Population: row[2].to_i,
      Population_density: row[3].to_i,
      Urban_population: row[5].to_i,
      Urban_population_coastal: row[6].to_i,
      GDP_per_capita: row[7].to_i,
      Land_area: row[12].to_i,
      Cropland_area: row[13].to_i,
      Pasture_area: row[14].to_i,
      Water_per_capita: row[17].to_i,
      Commercial_energy_consumption: row[31].to_i,
      Traditional_fuel_consumption: row[32].to_i,
      Commercial_hydroelectric_consumption: row[33].to_i
    )
    end

    CSV.foreach("lib/assets/CAIT Country CO2 Emissions.csv", :headers =>false) do |row |
      puts row.inspect #just so that we know the file's being read

      country_temp = row[0].to_s
      continent = Continent.select(:id).where(Country: country_temp)
      puts continent

      #create new model instances with the data
      Emission.create!(
      continent_id: continent,
      year: row[1].to_i,
      pollution: row[2].to_f,
    )
    end
  end
end

continent.rb

class Continent < ApplicationRecord
    has_many :emissions
    validates :Continent, :Country, :Population, :Population_density, :Urban_population, :Urban_population_coastal, :GDP_per_capita, :Land_area, :Cropland_area, :Pasture_area, :Water_per_capita, :Commercial_energy_consumption, :Traditional_fuel_consumption, :Commercial_hydroelectric_consumption, presence: true
end

эмиссии.rb

class Emission < ApplicationRecord
  belongs_to :continent
end

schema.rb

# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_10_18_200535) do

  create_table "continents", force: :cascade do |t|
    t.string "Continent"
    t.string "Country"
    t.integer "Population"
    t.integer "Population_density"
    t.integer "Urban_population"
    t.integer "Urban_population_coastal"
    t.integer "GDP_per_capita"
    t.integer "Land_area"
    t.integer "Cropland_area"
    t.integer "Pasture_area"
    t.integer "Water_per_capita"
    t.integer "Commercial_energy_consumption"
    t.integer "Traditional_fuel_consumption"
    t.integer "Commercial_hydroelectric_consumption"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "emissions", force: :cascade do |t|
    t.integer "continent_id"
    t.integer "year"
    t.float "pollution"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["continent_id"], name: "index_emissions_on_continent_id"
  end

end

1 Ответ

0 голосов
/ 20 октября 2019

Я решил свою проблему, поэтому решил опубликовать решение

Я переключил эту строку

continent = Continent.select(:id).where(Country: country_temp)

с этим кодом

continent = Continent.where(["Country = ?", country_temp])
continent = continent[0]
puts continent

Iполагаю, что проблема заключалась в том, что я использовал метод 'where', чтобы получить массив 'continents', чтобы соответствовать этому критерию, и я просто не устанавливал свою переменную в первую запись в массиве, чтобы я мог использовать метод 'id',«continent_id» не искал массив, и я передавал его.

CSV.foreach("lib/assets/CAIT Country CO2 Emissions.csv", :headers =>false) do |row|
      puts row.inspect #just so that we know the file's being read

      country_temp = row[0].to_s
      continent = Continent.where(["Country = ?", country_temp])
      continent = continent[0]
      puts continent

      #create new model instances with the data
      Emission.create!(
      continent_id: continent.id,
      year: row[1].to_i,
      pollution: row[2].to_f,
      )
    end

После этого я смог ссылаться на «выбросы» в контроллере «континент», чтобы я мог использовать «выбросы»данные с моими объектами 'континента'.

Надеюсь, это поможет, если кто-нибудь столкнется с подобной проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...