同一对象上的多个多态关联

Multiple polymorphic associations on the same object

我有一个 Flag 模型,该模型通过 FlagInstance 和 table:

上的多态 flaggable 连接到多个其他对象
table 'flag_instances'
flag_id
flaggable_id
flaggable_type
.....

有了 many_through,我可以获取任何可标记的对象,例如 user.flags,这很棒。

但是我试图标记有错误的对象并通知其他对象,所以我添加了

table 'flag_instances'
flag_id
flaggable_id
flaggable_type
notifiable_id
notifiable_type
.....

问题是,一个 User 可以有一个标志,并且可以 通知 一个标志。所以 user.flags 不够具体,无法告诉我哪个是 flag 哪个是 flag.

的通知

我想我需要改变关系:

user.rb
has_many :flag_instances, as: :flaggable, dependent: :destroy
has_many :flags, through: :flag_instances
has_many :flag_instances, as: :notifiable, dependent: :destroy
has_many :flags, through: :flag_instances

但我不确定要将它们更改为什么。有人可以提出解决方案吗?

注意:标志和标志的通知都可以属于多个对象,因此它们都需要保持多态性。

谢谢

需要更改通知的关联。在这种情况下 user.rb:

has_many :flag_instances, as: :flaggable, dependent: :destroy
has_many :flags, through: :flag_instances

has_many :notifiables, as: :notifiable, dependent: :destroy, class_name: 'FlagInstance'
has_many :notifications, through: :notifiables, class_name: 'Flag'

注意:您可能还需要提供 foreign_key 以防 Rails 协会无法自行获取密钥。

每个关联必须有一个唯一的名称 - 否则后面的定义只会覆盖前面的定义。

此处第三行覆盖第一行:

has_many :flag_instances, as: :flaggable, dependent: :destroy
has_many :flags, through: :flag_instances
has_many :flag_instances, as: :notifiable, dependent: :destroy

要引用正确的关联,我们需要这样设置用户模型:

class User < ApplicationRecord
  has_many :flag_instances_as_flaggable, 
     as: :flaggable
     class_name: 'FlagInstance'
  has_many :flags_as_flaggable, 
     through: :flag_instances_as_flaggable, 
     source: :flag
  has_many :flag_instances_as_notifiable, 
     as: :notifiable
     class_name: 'FlagInstance'
  has_many :flags_as_notifiable,
     through: :flag_instances_as_notifiable,
     source: :flag
end

在您的情况下,您可能希望使用关注点来保持干燥:

module Flaggable
  extend ActiveSupport::Concern
  included do
    has_many :flag_instances_as_flaggable, 
      as: :flaggable,
      class_name: 'FlagInstance'
    has_many :flags_as_flaggable,
      through: :flag_instances_as_flaggable, 
      source: :flag
  end
end

module Notifiable
  extend ActiveSupport::Concern
  included do
    has_many :flag_instances_as_notifiable, 
      as: :notifiable,
      class_name: 'FlagInstance'
    has_many :flags_as_notifiable,
      through: :flag_instances_as_notifiable,
      source: :flag
  end
end

class User < ApplicationRecord
  include Flaggable
  include Notifiable
end