2009-11-05 12 views
111

Ludzie,ActiveRecord, has_many: through i Polymorphic Associations

Chcesz się upewnić, że rozumiem to poprawnie. I proszę zignoruj ​​tutaj przypadek dziedziczenia (SentientBeing), próbując zamiast tego skupić się na modelach polimorficznych w has_many: poprzez relacje. To powiedziawszy, należy rozważyć następujące ...

class Widget < ActiveRecord::Base 
    has_many :widget_groupings 

    has_many :people, :through => :widget_groupings, :source => :person, :conditions => "widget_groupings.grouper_type = 'Person'" 
    has_many :aliens, :through => :widget_groupings, :source => :alien, :conditions => "video_groupings.grouper_type = 'Alien'" 
end 

class Person < ActiveRecord::Base 
    has_many :widget_groupings, :as => grouper 
    has_many :widgets, :through => :widget_groupings 
end 

class Alien < ActiveRecord::Base 
    has_many :widget_groupings, :as => grouper 
    has_many :widgets, :through => :widget_groupings 
end 

class WidgetGrouping < ActiveRecord::Base 
    belongs_to :widget 
    belongs_to :grouper, :polymorphic => true 
end 

w idealnym świecie, chciałbym, otrzymał widget a osoba, zrobić coś takiego:

widget.people << my_person 

Jednak, kiedy zrobić to, zauważyłem, że "typ" grupy "grouper" zawsze ma wartość null w widget_groupings. Jednakże, jeśli mam coś takiego:

widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person}) 

Wtedy wszystkie prace, jak bym się normalnie spodziewał. Wydaje mi się, że nigdy nie widziałem, żeby to miało miejsce w przypadku nie polimorficznych skojarzeń i chciałem tylko wiedzieć, czy jest to coś konkretnego dla tego przypadku użycia, czy też potencjalnie patrzę na błąd.

Dzięki za pomoc!

Odpowiedz

156

Istnieje known issue z Rails 3.1.1, który łamie tę funkcję. Jeśli ten problem występuje po raz pierwszy, zaktualizuj go. Został on naprawiony w wersji 3.1.2

Jesteś tak blisko. Problem polega na tym, że niewłaściwie używasz opcji: source. : źródło powinno wskazywać na polimorficzny związek belongs_to. Następnie wszystko, co musisz zrobić, to określić: source_type dla relacji, którą próbujesz zdefiniować.

Ta poprawka do modelu Widget powinna umożliwić wykonanie dokładnie tego, czego szukasz.

class Widget < ActiveRecord::Base 
    has_many :widget_groupings 

    has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person' 
    has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien' 
end 
+0

O mój Boże, który jest tak boleśnie oczywisty, że nie mogę uwierzyć, że przeszmuglowałem nad nim. Dzięki EmFi! – Cory

+0

Nie ma problemu, myślę, że zadręczałem się przez około jeden dzień nad tym, jak to zrobić, gdy pierwszy raz go spotkałem. Nie pomogło mi to, że była to jedna z pierwszych rzeczy, które próbowałem zrobić w Railsach, które nie wymagały zastosowania się do tutorialu/książki. – EmFi

+0

Dziękuję EmFi. – jdl

-3

ma wiele: przez i polimorficznych nie działają razem. Jeśli spróbujesz uzyskać do nich bezpośredni dostęp, powinien wystąpić błąd. Jeśli się nie mylę, musisz napisać widget.people i procedurę push.

Nie sądzę, że to błąd, to tylko coś, co nie zostało jeszcze zaimplementowane. Mogę sobie wyobrazić, że widzimy to w funkcji, ponieważ każdy ma przypadek, w którym mógłby go użyć.

+5

one działają razem. Na przykład: has_many: subscriptions,: as =>: subscribable has_many: subscribers,: through =>: subscriptions,: source =>: user – ScottJ

+0

Podam przykład mojego kodu błędu jako osobnego postu w pobliżu przyszłość :) Oszczędziłoby mi mnóstwo bólu głowy, aby dowiedzieć się, jak ominąć ten błąd. – cgr

3

Jak wspomniano powyżej, to nie działa z szynami 3.1.1 z powodu błędu na: źródła, ale to ustalone w Rails 3.1.2

+0

https://github.com/rails/rails/issues/3271 – EmFi

Powiązane problemy