在多颗痣 rails 之间共享 has_and_belongs_to_many 的最佳方式

best way to share has_and_belongs_to_many between multiple moles rails

所以目前我有一个类别和一个文章模型:

class Article < ApplicationRecord
  has_and_belongs_to_many :categories
end

class Category < ApplicationRecord
end

效果很好。但现在我想扩展系统并引入其他模型,这些模型也将以类似的方式分配类别:

class Article < ApplicationRecord
  has_and_belongs_to_many :categories
end

class Project < ApplicationRecord
  has_and_belongs_to_many :categories
end

我想知道,不是为每个模型创建新的连接 table,是否可以共享一个连接 table?或者这实际上是更可取的方法,如果是这样,为什么?

使用polymorphic associations. But that doesn't work with has_and_belongs_to_many so we need to set up the many-to-many relationship manually. See 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_idt.string :categorable_type 来存储关系的 ID 和 class。 categorable_type: 'Article', categorable_id: 5 引用 ID 为 5 的文章。

因为它是多对多的,所以不需要修改 articlesprojects 表。

多态关联很方便,但由于它不使用外键,因此数据库无法强制执行参照完整性。这是由 Rails 处理的。这在 Rails 应用程序中是可以接受的,因为数据库通常只由 Rails 模型控制。 Rails模型和数据库可视为一个整体。