11

Więc tutaj jest klasa próbkaSzyny has_many poprzez aliasing ze źródła i source_type dla wielu typów

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.vc_firms company.angels i działa zgodnie z oczekiwaniami. Ale w jaki sposób mam @ company.investors, które składają się z obu typów źródeł? To zadziałałoby dla wszystkich polimorfizmów w kolumnie Inwestor tabeli Inwestycje? a może sposób użycia zakresu do scalenia wszystkich typów source_type?

Model inwestycyjny wygląda następująco:

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 

anioły są powiązane poprzez osoba model

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

odpowiedniego modelu organizacja finansowa stowarzyszenia:

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

Odpowiedz

14

Poprzednie rozwiązanie było źle, źle zrozumieli jeden ze stosunków.

Szyny nie mogą zapewnić metody has_many przekraczającej relację polimorficzną. Powodem jest to, że instancje są rozłożone na różne tabele (ponieważ mogą należeć do różnych modeli, które mogą znajdować się na tej samej tabeli lub nie). Tak więc musisz podać typ_źródła, jeśli przekraczasz zależność polimorficzną belongs_to.

Mimo, że zakładając, można użyć dziedziczenia w Inwestora jak ten:

class Investor < ActiveRecord::Base 
    has_many :investments 
end 

class VcFirm < Investor 
end 

class Angel < Investor 
end 

The byłbyś w stanie usunąć opcję polimorficzny z inwestycji:

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

    ......... 
end 

A byłbyś udało się przekroczyć relację i zakres jej warunków:

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

Nie działa. Oto błąd: ActiveRecord :: HasManyThroughAssociationPolymorphicSourceError: Nie można mieć powiązania firmowego "Company # investors" has_many: through na obiekcie polimorficznym "Investor # investor" bez "source_type". Spróbuj dodać "source_type:" Investor "" do definicji "has_many: through". –

+0

@MichaelKMadison Poprawiłem odpowiedź – polmiro

+0

Hmmm ... wtedy musiałbym przechowywać ludzi i organizacje finansowe w tym samym stole, co nie jest w porządku. –

2

Dodałem metoda klasy Company że pobiera wszystkich inwestorów dla spółki poprzez połączenie ze stołem inwestycji:

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 wyglądał całkiem pomocne dla czytania na :source vs. :source_type.

Mam nadzieję, że pomoże!