【问题标题】:Creating a foreign key on an exisiting column in Ruby on Rails在 Ruby on Rails 中的现有列上创建外键
【发布时间】:2020-11-16 23:14:32
【问题描述】:

我正在尝试在 Ruby on Rails 中创建两个表,这两个表都将通过播种 CSV 文件来填充。这两个文件都已经包含一个 ID 列 fsa_id,我想将其用作我的表的主键/外键。

到目前为止,我有以下表迁移:

名字:

  class CreateNames < ActiveRecord::Migration[6.0]
  def change
    create_table :names do |t|
      t.integer :fsa_id
      t.string :name

      t.timestamps
    end
  end
end

地点:

class CreateLocations < ActiveRecord::Migration[6.0]
  def change
    create_table :locations do |t|
      t.integer :fsa_id
      t.string :adress
      t.string :postcode
      t.integer :lattitude
      t.integer :longitude
      t.string :local_authority

      t.timestamps
    end
  end
end

我要做的是使fsa_id 成为名称表上的主键和位置表上的外键。

据我了解,我可以通过将以下内容添加到位置迁移文件来做到这一点:

class CreateLocations < ActiveRecord::Migration[6.0]
  def change
    create_table :locations do |t|
      t.integer :fsa_id
      t.string :adress
      t.string :postcode
      t.integer :lattitude
      t.integer :longitude
      t.string :local_authority

      t.timestamps
    end
    # Adds a foreign key constraint to the fsa_id column
    # Links to the names table which uses the same named column.
    add_foreign_key :locations, 
                :names, 
                column: :fsa_id,
                primary_key: :fsa_id
  end
end

但是,当我添加它并尝试运行 rails db:migrate 时,我收到以下错误:

== 20201116221428 CreateLocations: migrating ==================================
-- create_table(:locations)
   -> 0.0017s
-- add_foreign_key(:locations, :names, {:column=>:fsa_id, :primary_key=>:fsa_id})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: foreign key mismatch - "locations" referencing "names"
/home/jonathon/Projects/waad/jpd_individual_2020/db/migrate/20201116221428_create_locations.rb:15:in `change'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/rails:9:in `<top (required)>'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'

Caused by:
ActiveRecord::StatementInvalid: SQLite3::SQLException: foreign key mismatch - "locations" referencing "names"
/home/jonathon/Projects/waad/jpd_individual_2020/db/migrate/20201116221428_create_locations.rb:15:in `change'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/rails:9:in `<top (required)>'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'

Caused by:
SQLite3::SQLException: foreign key mismatch - "locations" referencing "names"
/home/jonathon/Projects/waad/jpd_individual_2020/db/migrate/20201116221428_create_locations.rb:15:in `change'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/rails:9:in `<top (required)>'
/home/jonathon/Projects/waad/jpd_individual_2020/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

我试过环顾四周,但大多数答案似乎都假设要使用表的 id,或者表会自行增长。

为了完整参考,用于为数据库提供种子的 CSV 文件的布局如下:

names.csv:

locations.csv:

如果有人能帮助解决这个问题,我将不胜感激。

编辑:

我在生产中使用 Postgress:

我的 Gemfile 如下:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.4'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4', '>= 1.4.2', group: :production
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
gem 'chartkick'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :production do
  gem 'pg'
end
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
 end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

【问题讨论】:

    标签: ruby-on-rails ruby csv activerecord


    【解决方案1】:

    如果您想修改或添加外键到现有表,您应该创建一个新的迁移以避免在生产中破坏您的代码。

    【讨论】:

      【解决方案2】:

      CreateNames 迁移时,您可以使用primary_key: :fsa_id 选项。

      class CreateNames < ActiveRecord::Migration[6.0]
        def change
          create_table :names, primary_key: :fsa_id do |t|
            t.string :name
      
            t.timestamps
          end
        end
      end
      
      

      CreateLocations 迁移与您发布的一样。

      您还需要在以下模型中设置关联:

      class Name < ApplicationRecord
        has_one :location, primary_key: :fsa_id
      end
      
      class Location < ApplicationRecord
        belongs_to :name, foreign_key: :fsa_id, primary_key: :fsa_id
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 2020-02-24
        相关资源
        最近更新 更多