10

다형성 연관을 사용할 때 일부 유형에만있는 서브 모델에 포함을 실행할 수 있습니까?Ruby on Rails : : 서브 모델과 다형성 연관에 포함

예 :

내가 좋아하는 뭔가를하고 싶은거야 뷰에서
class Container 
    belongs_to :contents, :polymorphic => true 
end 
class Food 
    has_one :container 
    belongs_to :expiration 
end 
class Things 
    has_one :container 
end 

: 따라서

<% c = Containers.all %> 
<% if c.class == Food %> 
    <%= food.expiration %> 
<% end %> 

을, 나는 열망 부하 전 C를로드 만료를하고 싶습니다 왜냐하면 나는 그들이 모든 것을 필요로 할 것이기 때문이다. 그렇게 할 방법이 있습니까? 정규식을 정의하는 것만으로, 모든 enclosed types에 서브 모델 만료가 없기 때문에 include가 오류를 발생시킵니다.

답변

24

편집 대답은

나는 최근에 당신이 다형성 유형 열을 기준으로 필터링 할 때 레일이 다형성 협회의 열망로드를 지원하는 것을 알아 냈다. 따라서 가짜 연관성을 선언 할 필요가 없습니다.

class Container 
    belongs_to :content, :polymorphic => true 
end 

지금 container_type하여 Container를 쿼리합니다. 한 쿼리에서 다형성 개체를 포함하는 직접적인 방법이 없기 때문에

containers_with_food = Container.find_all_by_content_type("Food", 
          :include => :content) 

containers_with_thing = Container.find_all_by_content_type("Thing", 
          :include => :content) 

올드 답변

이 해킹이다.

class Container 
    belongs_to :contents, :polymorphic => true 
    # add dummy associations for all the contents. 
    # this association should not be used directly 
    belongs_to :food 
    belongs_to :thing 
end 

지금 container_type하여 Container를 쿼리합니다. 당신이 다른 열을 필요로하는 하나의 SQL에서이 작업을 수행 할 수있는 방법이 없습니다

containers_with_food = Container.find_all_by_content_type("Food", 
          :include => :food) 

containers_with_thing = Container.find_all_by_content_type("Thing", 
          :include => :thing) 

두 SQL 결과를 데이터베이스에 호출하는 (레일 모든 :include에 대해 하나 개의 SQL을 실행하면서 실제로는 4 호출입니다) 다른 콘텐츠 유형에 대해 설정됩니다.

경고 : 예기치 않은 결과가 발생하므로 클래스의 더미 연결을 직접적으로 사용해서는 안됩니다.

예 : contents 테이블의 첫 번째 개체에 음식이 들어 있다고 가정 해 보겠습니다.

Content.first.food # will work 
Content.first.thing 

두 번째 호출은 작동하지 않습니다. Food 개체가 가리키는 ID가 ContentThing 개체를 제공 할 수 있습니다.

+0

몇 가지 새로운 정보를 바탕으로 내 대답을 업데이트했습니다. –

+1

다형성 연관의 eager-loading은 어떤 버전의 ActiveRecord에서 작동합니까? 3.2.3에서 작동하지 않습니다. – nicholaides

+0

@nicholaides 3.2.3에서 작동합니다. 열렬한 로딩은 다형성 유형 열로 필터링 할 때만 발생합니다. 발생한 오류가 무엇입니까? –