11

Così qui è una lezione di provaRails has_many attraverso aliasing con la fonte e source_type per più tipi di

class Company < ActiveRecord::Base 
    has_many :investments 
    has_many :vc_firms, through: :investments, source: :investor, source_type: 'VentureFirm' 
    has_many :angels, through: :investments, source: :investor, source_type: 'Person' 
end 

@ company.angels e @ company.vc_firms funziona come previsto. Ma come vorrei che @ company.investors comprendesse entrambi i tipi di fonte? Ciò funzionerebbe per tutti i polimorfismi nella colonna degli investitori della tabella Investimenti? o forse un modo di usare uno scope per unire tutti i source_type?

modello di investimento simile a questa:

class Investment < ActiveRecord::Base 
    belongs_to :investor, polymorphic: true 
    belongs_to :company 

    validates :funding_series, presence: true #, uniqueness: {scope: :company} 
    validates :funded_year, presence: true, numericality: true 
end 

Angeli sono associati attraverso il modello persona

class Person < ActiveRecord::Base 
    has_many :investments, as: :investor 
end 

rilevanti associazioni modello organizzazione finanziaria:

class FinancialOrganization < ActiveRecord::Base 
    has_many :investments, as: :investor 
    has_many :companies, through: :investments 
end 

risposta

14

soluzione precedente era sbagliato, ho frainteso uno dei rapporti.

Rails non può fornire un metodo has_many che attraversa una relazione polimorfica. Il motivo è che le istanze sono distribuite attraverso tabelle diverse (perché possono appartenere a modelli diversi che potrebbero essere o meno sulla stessa tabella). Pertanto, è necessario fornire il tipo_origine se si attraversa una relazione polymorphic appartiene alla proprietà.

Detto questo, supponendo che si potrebbe usare l'ereditarietà nel Investor come questo:

class Investor < ActiveRecord::Base 
    has_many :investments 
end 

class VcFirm < Investor 
end 

class Angel < Investor 
end 

La si sarebbe in grado di rimuovere l'opzione polimorfico da investimenti:

class Investment < ActiveRecord::Base 
    belongs_to :investor 
    belongs_to :company 

    ......... 
end 

e si sarebbe in grado di attraversare la relazione e portata con condizioni:

class Company < ActiveRecord::Base 
    has_many :investments 
    has_many :investors, through :investments 
    has_many :vc_firms, through: :investments, source: :investor, conditions: => { :investors => { :type => 'VcFirm'} } 
    has_many :angels, through: :investments, source: :investor, conditions: => { :investors => { :type => 'Angel'} } 
end 
+0

Non funziona. Ecco l'errore: ActiveRecord :: HasManyThroughAssociationPolymorphicSourceError: Impossibile avere has_many: tramite associazione 'Company # investors' sull'oggetto polimorfico 'Investitore # investitore' senza 'source_type'. Prova ad aggiungere 'source_type: "Investitore"' a 'has_many: through' definizione. –

+0

@MichaelKMadison Ho corretto la risposta – polmiro

+0

Hmmm ... quindi dovrei memorizzare persone e organizzazioni finanziarie nello stesso tavolo che non sembra giusto. –

2

Ho aggiunto un metodo per la classe Company che recupera tutti gli investitori per l'azienda unendo con la tabella degli investimenti:

class Company < ActiveRecord::Base 
    has_many :investments 
    has_many :vc_firms, :through => :investments, :source => :investor, :source_type => 'VcFirm' 
    has_many :angels, :through => :investments, :source => :investor, :source_type => 'Angel' 

    def investors 
    Investor.joins(:investments).where(:investments => {:company_id => id}) 
    end 
end 

http://www.brentmc79.com/posts/polymorphic-many-to-many-associations-in-rails sembrava abbastanza utile per la lettura su :source vs. :source_type.

Spero che aiuti!