Используйте polymorphi c ассоциаций . Но это не работает с has_and_belongs_to_many
, поэтому нам нужно установить отношение «многие ко многим» вручную. См. этот ответ для получения дополнительной информации .
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
для хранения идентификатора и класса отношений. categorable_type: 'Article', categorable_id: 5
ссылается на Статью с идентификатором 5.
Так как это множество ко многим, никаких модификаций для таблиц articles
или projects
не требуется.
Polymorphi c ассоциации удобны, но поскольку база данных не использует внешние ключи, база данных не может обеспечить ссылочную целостность. Это обрабатывается Rails. Это приемлемо в приложении Rails, поскольку база данных обычно контролируется только моделью Rails. Модель Rails и базу данных можно рассматривать как единое целое.