使用polymorphic associations。但这不适用于has_and_belongs_to_many,因此我们需要手动设置多对多关系。见this answer for more。
class Category < ApplicationRecord
has_many :category_relations
end
class CategoryRelation < ApplicationRecord
belongs_to :categories
belongs_to :categorable, polymorphic: true
end
class Article < ApplicationRecord
has_many :category_relations, as: categorable
has_many :categories, through: :category_relations
end
class Project < ApplicationRecord
has_many :category_relations, as: categorable
has_many :categories, through: :category_relations
end
迁移看起来像......
class CreateCategorable < ActiveRecord::Migration[5.2]
def change
create_table :categories do |t|
t.string :name
t.timestamps
end
create_table :categories_relations, id: false do |t|
t.references :categories, index: true
t.references :categorable, polymorphic: true, index: true
end
end
end
t.references :categorable, polymorphic: true, index: true 是一种方便的方法,它设置t.bigint :categorable_id 和t.string :categorable_type 来存储关系的ID 和类。 categorable_type: 'Article', categorable_id: 5 引用 ID 为 5 的文章。
由于是多对多,无需修改articles 或projects 表。
多态关联很方便,但是因为它不使用外键,所以数据库不能强制引用完整性。这是由 Rails 处理的。这在 Rails 应用程序中是可以接受的,因为数据库通常只由 Rails 模型控制。 Rails 模型和数据库可以视为一个单元。