ActiveRecord, ma wiele: Poprzez, i polimorficznych skojarzeń

Ludzie,

Chcę się upewnić, że dobrze to Rozumiem. I proszę pominąć tutaj przypadek dziedziczenia (SentientBeing), starając się zamiast tego skupić się na modelach polimorficznych w has_many: poprzez relacje. To powiedziawszy, rozważ następujące rzeczy...
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, biorąc pod uwagę Widget i osobę, zrobić coś w stylu:

widget.people << my_person

Jednak, kiedy to robię, zauważyłem ,że 'type ''grupy' jest zawsze null w widget_groupings. Jednakże, jeśli do coś w stylu:

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

Wtedy wszystko działa tak, jak normalnie bym się spodziewał. Nie sądzę, że kiedykolwiek widziałem, aby to miało miejsce z nie polimorficznymi skojarzeniami i chciałem tylko wiedzieć, czy to było coś specyficznego dla tego przypadku użycia, czy potencjalnie gapię się na błąd.

Dzięki za pomoc!

Author: Ryan Bigg, 2009-11-05

3 answers

Istnieje znany problem z Rails 3.1.1, który łamie tę funkcjonalność. Jeśli masz ten problem, najpierw spróbuj uaktualnić, został on naprawiony w 3.1.2

Jesteś tak blisko. Problem w tym, że nadużywasz opcji: source. : source powinien wskazywać na zależność polymorphic belongs_to. Następnie wystarczy podać :source_type dla relacji, którą próbujesz zdefiniować.

Ta poprawka do modelu widżetu powinna pozwolić Ci zrobić dokładnie to, co jesteś Szukam.

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
 158
Author: EmFi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 09:09:39

Jak wspomniano powyżej, to nie działa z rails 3.1.1 z powodu błędu na: source, ale jest naprawione w Rails 3.1.2

 3
Author: scottkf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-04 13:02:06

Ma wiele: Przez i polimorficzne nie działają razem. Jeśli spróbujesz uzyskać do nich bezpośredni dostęp, powinien to spowodować błąd. Jeśli się nie mylę, musisz ręcznie napisać widget.ludzie i rutyna pchania.

Myślę, że to nie jest błąd, to po prostu coś, co nie zostało jeszcze zaimplementowane. Wyobrażam sobie, że widzimy to w funkcji, ponieważ każdy ma przypadek, w którym mógłby go użyć.

 -3
Author: cgr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-05 23:21:51