Начните с установки правильного типа столбца внешнего ключа и установите ограничение внешнего ключа, указывающее на правый столбец:
class CreateComments < ActiveRecord::Migration[6.0]
def change
create_table :comments do |t|
t.string :title
t.string :note
t.references :book, type: :string, column_name: :isbn
t.timestamps
end
end
end
Я ожидаю, что таблица "комментарии" сгенерированный будет содержать столбец «isbn» (строка) после переноса базы данных, но на самом деле сгенерированная таблица «comments» содержала вместо него «book_id» (целое число).
Миграции на самом деле намного проще и тупее, чем вы думаете. Это просто DSL, который создает SQL операторов. На самом деле он никак не знает о другой таблице, поэтому он не может знать, что books.isbn
является строковым столбцом. Он просто использует тип по умолчанию для add_reference
, который :integer
. Rails управляется соглашением, а не искусственным интеллектом.
Если вы хотите назвать столбец чем-то вроде book_isbn
, вы должны сделать это в два этапа вместо этого:
class CreateComments < ActiveRecord::Migration[6.0]
def change
create_table :comments do |t|
t.string :title
t.string :note
t.string :book_isbn
t.timestamps
end
add_foreign_key :comments, :books,
column: "book_isbn", primary_key: "isbn"
end
end
Затем настройте модель books для использования вашего нетрадиционного первичного ключа:
class Book < ApplicationRecord
self.primary_key = :isbn
has_many :comments,
foreign_key: :book_isbn # default is book_id
end
На стороне комментария необходимо настроить ассоциацию belongs_to
так, чтобы она указывала на books.isbn
вместо books.id
.
class Comment < ApplicationRecord
belongs_to :book, primary_key: :isbn
end
references
не является допустимым параметром для belongs_to
.
ArgumentError (Unknown key: :references. Valid keys are: :class_name, :anonymous_class, :foreign_key, :validate, :autosave, :foreign_type, :dependent, :primary_key, :inverse_of, :required, :polymorphic, :touch, :counter_cache, :optional, :default)