Добавление ссылки на нецелочисленный столбец в миграции rails

Сегодня я изучил несколько вопросов по этой теме. Я знаю это, я могу использовать t.references в миграции, чтобы добавить ссылку. Но если таблица имеет нецелочисленный первичный ключ, как мне добавить ссылку на этот столбец?

У меня есть таблица с этим определением

    create_table :sessions, id: false do |t|
      t.string  :session, primary_key: true, limit: 10  

      t.timestamps null: false
    end

Как мне добавить ссылку на столбец session (имя здесь не имеет значения), который является строкой из другой миграции таблицы. Я тестировал с t.references, но это просто добавило целочисленный столбец. Я знаю, что могу использовать add column. Но как это сделать без метода from create_table напрямую?

Разъяснение для флага дублирования
Этот вопрос помечен как дублирующий этот вопрос, но на самом деле это нет. Потому что я не спрашиваю о настройке таблицы с нецелочисленным первичным ключом, отличным от значения по умолчанию, потому что я уже настроил эту таблицу. Я спрашиваю о ссылке на этот тип таблицы из другой таблицы.


person Anwar    schedule 23.08.2015    source источник
comment
возможный дубликат нецелого первичного ключа rails   -  person ABMagil    schedule 23.08.2015
comment
@ABMagil Я не думаю, что это дубликат, поскольку Анвар спрашивает об ссылках на нецелочисленные первичные ключи, а не о самих первичных ключах.   -  person eirikir    schedule 23.08.2015


Ответы (4)


Вместо использования помощника ссылок вам нужно будет использовать строковый тип и добавить индекс для более быстрого поиска. Если ваша другая модель "Record":

rails generate migration AddSessionIdToRecords session:string:index

Что должно генерировать миграцию следующим образом:

def change
  add_column :records, :session_id, :string
  add_index :records, :session_id
end

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

class Session < ActiveRecord::Base
  self.primary_key = "session"

  has_many :records, primary_key: "session"
end

class Record < ActiveRecord::Base
  belongs_to :session, primary_key: "session"
end
person eirikir    schedule 23.08.2015
comment
У меня почти такая же настройка, но я думаю, что это foreign_key: "session" вместо primary_key: "session". Вы должны проверить - person Anwar; 24.08.2015
comment
Как вы назвали столбец в другой таблице (records)? Это внешний_ключ, поэтому, если вы назовете его session, внешний_ключ будет "session". - person eirikir; 24.08.2015
comment
Дело в том, что я должен использовать параметр external_key, а не параметр primary_key - person Anwar; 24.08.2015

На самом деле вам не нужно добавлять primary_key в класс Session & Record

def change
  add_column :records, :session_id, :string
  add_index :records, :session_id
  add_foreign_key :records, :sessions, column: :session_id, primary_key: "your_primary_key_name_in_sessions_table"
end

и это будет все.

person Edison Su    schedule 27.12.2016
comment
Почему я должен использовать :session_id как string? - person Anwar; 27.12.2016

Я пришел к выводу, что без использования foreign_key, представленного в rails 4.2, я не могу по-настоящему ссылаться на другой столбец, создавая только индекс, как это предлагается этот ответ от eirikir.

С рельсов 4.2 я могу использовать такой внешний ключ

Миграция таблицы сеанса

create table :sessions, id: false do |t|
  t.string "session", primary_key: true
  t.timestamp null: false
end

Чтобы таблица записей ссылалась на первичный ключ session

create table :records do |t|
  t.string "session", null: false
  ..
  .. # other attributes
end

add_index :records, :session
add_foreign_key :records, :sessions, column: :session, primary_key: :session

Здесь опция column: определяет, в каком столбце я хочу создать внешний ключ, а опция primary_key: исправляет первичный ключ ссылочной таблицы, которая здесь session.

person Anwar    schedule 18.10.2015

Начиная с версии rails 4.2.7 вы можете указать type в помощнике add_reference. Предположим, у вас есть таблица records, и вы хотите иметь ссылку на sessions внутри records. Затем вы можете сделать следующее:

add_reference :records, :sessions, type: :string, foreign_key: {to_table: :sessions, primary_key: :session}
person bilash.saha    schedule 15.03.2020