1

Возможно ли иметь полиморфную ассоциацию «has_many» в рельсах?rails polymorphic has_many association

У меня была таблица notifications имевшая communication_method, который может быть либо адрес электронной почты или номер телефона:

change_table :notifications do |t| 
    t.references :communication_method, :polymorphic => true 
end 

class Notification < ActiveRecord::Base 
    belongs_to :communication_method, :polymorphic => true 
    belongs_to :email_address, foreign_key: 'communication_method_id' 
    belongs_to :phone_number, foreign_key: 'communication_method_id' 
end 

module CommunicationMethod 
    def self.included(base) 
    base.instance_eval do 
     has_many :notifications, :as => :communication_method, :inverse_of => :communication_method, :dependent => :destroy 
    end 
    end 
end 

class EmailAddress 
    include CommunicationMethod 
end 

class PhoneNumber 
    include CommunicationMethod 
end 

теперь я хочу, чтобы иметь более одного способа связи за уведомлениями, возможно ли это? (что-то вроде has_many :communication_methods, :polymorphic => true) Я думаю, мне также понадобится миграция в другом, чтобы создать множество таблиц уведомлений для методов связи

ответ

1

Как я знаю, Rails до сих пор не поддерживает полиморфные ассоциации has_many. Я решал это, добавляя новую промежуточную модель, которая имеет полиморфную ассоциацию. В вашем случае это может быть, как следующее:

class Notification < ActiveRecord::Base 
    has_many :communication_method_links 
    has_many :email_communication_methods, :through => :communication_method_links, :class_name => 'EmailAddress' 
    has_many :email_communication_methods, :through => :communication_method_links, :class_name => 'PhoneNumber' 
    belongs_to :email_address, foreign_key: 'communication_method_id' 
    belongs_to :phone_number, foreign_key: 'communication_method_id' 
end 

class CommunicationMethodLink < ActiveRecord::Base 
    belongs_to :notification 
    belongs_to :communication_methods, :polymorphic => true 
end 

module CommunicationMethod 
    def self.included(base) 
    base.instance_eval do 
     has_many :communication_method_links, :as => :communication_method, :inverse_of => :communication_method, :dependent => :destroy 
    end 
    end 
end 

class EmailAddress 
    include CommunicationMethod 
end 

class PhoneNumber 
    include CommunicationMethod 
end 

Так что миграция CommunicationMethodLink будет выглядеть следующим образом:

create_table :communication_method_links do |t| 
    t.references :notification 
    t.references :communication_method, :polymorphic => true 
end