Несколько полиморфных ассоциаций на одном объекте - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть модель Flag, которая соединена с несколькими другими объектами с FlagInstance и полиморфной flaggable в этой таблице:

table 'flag_instances'
flag_id
flaggable_id
flaggable_type
.....

С has__________ * через - я могу получить любуюпометить объект, как 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

Но я не уверен, что поменять их.Может кто-нибудь предложить решение?

Примечание: и флаги, и уведомления о флагах могут принадлежать нескольким объектам, поэтому они оба должны оставаться полиморфными.

Спасибо

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Каждая ассоциация должна иметь уникальное имя - в противном случае более позднее определение просто перезапишет предыдущую.

Здесь третья строка перезаписывает первую строку:

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
0 голосов
/ 16 ноября 2018

Ассоциация для уведомляемых должна быть изменена. В этом случае 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 не сможет подобрать сам ключ.

...