Nano Hash - криптовалюты, майнинг, программирование

Как добавить внешний ключ в миграцию, где в справочной таблице нет столбца идентификатора

Я пытаюсь добавить новую таблицу в свой проект Rails с несколькими ссылками на другие таблицы. Однако внешние таблицы не имеют столбцов :id; Я настроил их так, чтобы у каждого из них был столбец строки :code вместо их первичных ключей.

Вот пример одной таблицы, на которую я буду ссылаться:

class CreateReasons < ActiveRecord::Migration[5.2]
  def up
    create_table :reasons, id: false do |t|
      t.string :code
      t.string :description

      t.timestamps
    end
    execute "ALTER TABLE reasons ADD PRIMARY KEY (code);"
  end

  def down
    drop_table :reasons
  end
end

Полученное описание Postgres именно то, что я хочу:

development-# \d reasons
                           Table "public.reasons"
   Column    |            Type             | Collation | Nullable | Default 
-------------+-----------------------------+-----------+----------+---------
 code        | character varying           |           | not null | 
 description | character varying           |           |          | 
 created_at  | timestamp without time zone |           | not null | 
 updated_at  | timestamp without time zone |           | not null | 
Indexes:
    "reasons_pkey" PRIMARY KEY, btree (code)

Я хочу, чтобы моя новая таблица, назовем ее TestModel, имела столбец с именем :reason_code, который является ссылкой внешнего ключа на первичный ключ таблицы reasons.

Что я пробовал:

  1. add_reference :test_models, :reasons, column: :code, type: :string, name: :reason_code, foreign_key: true под созданием таблицы. Ошибка PG::UndefinedColumn: ERROR: column "id" referenced in foreign key constraint does not exist

  2. add_foreign_key :test_models, :reasons, column: :code, type: :string, name: :reason_code под созданием таблицы. Ошибка PG::UndefinedColumn: ERROR: column "code" referenced in foreign key constraint does not exist

  3. Внутри создания таблицы: t.references :reason_code, foreign_key: { to_table: :reasons } и t.references :reason_code, foreign_key: { to_table: :reasons, column: :code } оба дают мне ошибку PG::UndefinedColumn: ERROR: column "id" referenced in foreign key constraint does not exist

И несколько других перестановок этих функций. Есть ли способ сделать это в Rails, желательно без выполнения большего количества необработанного SQL?


  • Из любопытства, почему вы опускаете столбец id? Это похоже на напрашивание неприятностей (как вы сейчас испытываете). 17.08.2019

Ответы:


1

Вы должны иметь возможность использовать параметр primary_key при переносе внешнего ключа, по умолчанию он равен столбцу id, и именно поэтому вы получаете сообщение об ошибке:

add_foreign_key :test_models, :reasons, column: :reason_code, primary_key: :code

См. документацию по методу add_foreign_key, там есть дополнительная информация о нем https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_foreign_key

17.08.2019
  • Большое спасибо! Для всех, кто пытался сделать то же самое, полное решение требовало двух частей: 1. добавление столбца в виде строки в команду create_table: t.string :reason_code 2. добавление строки из @edariedl ниже создания таблицы. 19.08.2019
  • Лучший. Нам по-прежнему нужно указать атрибуты has и own_to для обеих моделей, верно? 05.10.2020
  • Конечно, если вы хотите получить доступ к связанным записям из этих моделей. Вам просто нужно правильно установить foreign_key и primary_key в определениях has_many и belongs_to, чтобы все заработало. 07.10.2020

  • 2

    Этот человек указывает на вашу миграцию должно выглядеть так:

    class CreateReasons < ActiveRecord::Migration
      def change
        create_table :products, id: false do |t|
          t.string :code, null: false
          t.string :description
    
          t.timestamps
        end
    
        add_index :products, :code, unique: true
      end
    end
    

    и что ваша модель должна выглядеть так:

    class Reason < ApplicationRecord
      self.primary_key = 'code'
    end
    
    17.08.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..