我对ROR并不陌生,现在正在做一个与书籍有关的课程项目。我有一个以字符串'isbn'作为其主键的“书”表,现在尝试用外键“ isbn”的书表添加另一个“注释”来引用“书”表。所以我的“ models / comment.rb”看起来像这样:
class Comment < ApplicationRecord
belongs_to :book, references: :isbn, type: :string
end
并且“ models / book.rb”是:
class Book < ApplicationRecord
has_many :comments, dependent: :destroy
end
我的“书”表如下所示:我希望数据库迁移后生成的“ comments”表将包含列“ isbn”(字符串),但实际上生成的“ comments”表包含“ book_id”(整数)。如何生成外键以引用“书”表中的字符串主键“ isbn”?
首先将外键列设置为正确的类型,然后将外键约束设置为指向右列:
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”(字符串),但实际上是“注释”生成的表包含“ book_id”(整数)。
实际上,迁移比您想象的要简单很多。它只是创建SQL语句的DSL。它实际上并没有以任何方式知道另一个表,因此它无法知道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
然后设置书籍模型以使用您的非传统主键:
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)