ActiveRecord, has_many : through 및 다형성 연관


117

여러분,

이것을 올바르게 이해하고 있는지 확인하고 싶습니다. 그리고 여기서 상속의 경우 (SentientBeing)를 무시하고 대신 has_many : through 관계에서 다형성 모델에 초점을 맞추십시오. 즉, 다음을 고려하십시오.

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

완벽한 세상에서 저는 위젯과 사람이 주어지면 다음과 같이하고 싶습니다.

widget.people << my_person

그러나이 작업을 수행 할 때 'grouper'의 '유형'이 widget_groupings에서 항상 null임을 알았습니다. 그러나 다음과 같은 경우 :

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

그런 다음 모든 것이 일반적으로 예상했던대로 작동합니다. 나는 이것이 다형성이 아닌 연결에서 발생하는 것을 본 적이 없다고 생각하며 이것이이 사용 사례에 특정한 것인지 아니면 잠재적으로 버그를 주시하고 있는지 알고 싶었습니다.

도움을 주셔서 감사합니다!

답변:


162

이 기능을 방해하는 Rails 3.1.1 의 알려진 문제 가 있습니다. 이 문제가있는 경우 먼저 업그레이드를 시도해보십시오. 3.1.2에서 수정되었습니다.

당신은 너무 가깝습니다. 문제는 : source 옵션을 잘못 사용하고 있다는 것입니다. : source는 다형 적 belongs_to 관계를 가리켜 야합니다. 그런 다음 정의하려는 관계에 대해 : source_type을 지정하기 만하면됩니다.

위젯 모델에 대한이 수정을 통해 원하는 작업을 정확하게 수행 할 수 있습니다.

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

너무나도 명백한 오 마이 갓 내가 그 위에 유약을 바른 것을 믿을 수 없습니다. 감사합니다 EmFi!
Cory

문제 없습니다. 처음 만났을 때 어떻게해야하는지에 대해 하루 정도 고민했던 것 같습니다. 튜토리얼 / 책을 따르지 않는 Rails에서 내가 시도한 첫 번째 작업 중 하나라는 것을 돕지 않았습니다.
EmFi 2009

1
scotkf가 지적했듯이 ActiveRecord 3.1.1에는이 동작을 차단하는 회귀가 있습니다. 3.1.2로 업그레이드하면이 솔루션이 작동합니다.
EmFi 2011

6
@Shtirlic이 언급 한 것과 동일합니다. source_type을 지정하지 않는 방법이 있으므로 혼합 된 결과 세트가 있습니까? 누군가 이것을 해결했다면 방법을 알고 싶습니다.
Damon Aw

3
여전히 Rails 4.2.0부터 작동합니다. 그러나 요즘 source_type과 두 개의 별도 연결없이 이것을 수행 할 수있는 방법이 있습니까?
Emeka

3

위에서 언급했듯이 이것은 : source의 버그로 인해 rails 3.1.1에서 작동하지 않지만 Rails 3.1.2에서 수정되었습니다.


-4

: through와 polymorphic은 함께 작동하지 않습니다. 직접 액세스하려고하면 오류가 발생합니다. 내가 착각하지 않았다면 widget.people과 push 루틴을 직접 작성해야합니다.

나는 그것이 버그라고 생각하지 않습니다. 그것은 단지 아직 구현되지 않은 것입니다. 모든 사람이 사용할 수있는 경우가 있기 때문에 기능에서 볼 수 있다고 생각합니다.


6
그들은 함께 일합니다. 예 : has_many : subscriptions, : as => : subscribable has_many : subscribers, : through => : subscriptions, : source => : user
ScottJ

가까운 장래에 내 실패한 코드의 예를 별도의 게시물로 던질 것입니다. :) 그 오류를 우회하는 방법을 알아내는 데 많은 골칫거리가 될 것입니다.
cgr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.