在多个痣轨道之间共享has_and_belongs_to_many的最佳方法

问题描述 投票:1回答:1

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

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

我想知道,不是为每个模型创建新的联接表,而是可以共享一个联接表吗?还是这实际上是更可取的方法,如果可以,为什么?

ruby-on-rails database-design database-migration rails-migrations
1个回答
2
投票

使用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_idt.string :categorable_type来存储关系的ID和类。 categorable_type: 'Article', categorable_id: 5引用ID为5的文章。

由于是多对多,因此无需修改articles表或projects表。

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

© www.soinside.com 2019 - 2024. All rights reserved.