복붙노트

[RUBY-ON-RAILS] 열망로드 다형성

RUBY-ON-RAILS

열망로드 다형성

레일 3.2을 사용하여이 코드에있어 문제점은 무엇입니까?

@reviews = @user.reviews.includes(:user, :reviewable)
.where('reviewable_type = ? AND reviewable.shop_type = ?', 'Shop', 'cafe')

그것은이 오류가 발생합니다 :

나는 reviewable.shop_type의 =를 제거하면? 조건은, 그것을 작동합니다.

나는 어떻게 (실제로 shop.shop_type 됨) reviewable_type 및 reviewable.shop_type을 기준으로 필터링 할 수 있습니까?

해결법

  1. ==============================

    1.내 생각 엔 당신의 모델은 다음과 같이이다 :

    내 생각 엔 당신의 모델은 다음과 같이이다 :

    class User < ActiveRecord::Base
      has_many :reviews
    end
    
    class Review < ActiveRecord::Base
      belongs_to :user
      belongs_to :reviewable, polymorphic: true
    end
    
    class Shop < ActiveRecord::Base
      has_many :reviews, as: :reviewable
    end
    

    당신은 여러 가지 이유로 해당 쿼리를 할 수 없습니다.

    이 문제를 해결하기 위해 명시 적 검토 및 상점 사이의 관계를 정의해야합니다.

    class Review < ActiveRecord::Base
       belongs_to :user
       belongs_to :reviewable, polymorphic: true
       # For Rails < 4
       belongs_to :shop, foreign_key: 'reviewable_id', conditions: "reviews.reviewable_type = 'Shop'"
       # For Rails >= 4
       belongs_to :shop, -> { where(reviews: {reviewable_type: 'Shop'}) }, foreign_key: 'reviewable_id'
       # Ensure review.shop returns nil unless review.reviewable_type == "Shop"
       def shop
         return unless reviewable_type == "Shop"
         super
       end
    end
    

    그럼 당신은 다음과 같이 조회 할 수 있습니다 :

    Review.includes(:shop).where(shops: {shop_type: 'cafe'})
    

    공지 사항 테이블 이름은 상점과 검토 가능한 아니라고. 데이터베이스에서 검토 가능한라는 테이블이 없어야한다.

    나는이 명시 적으로 관련 분야에서 쿼리에 추가 열망로드 할 수 있기 때문에 (가) 검토 및 상점 사이의 조인을 정의하는 것보다 더 쉽고 유연하게 생각합니다.

    이 필요하다는 이유는 여러 테이블의 다른 쪽 끝을 나타냅니다 가입 및 SQL 이후 액티브는 내가 아는 한, A는 검토 가능한 단독 기반으로 조인을 구축 할 수 있다는 것입니다, 당신은 저장된 값에 의해라는 이름의 테이블을 조인 할 수 없습니다 열이다. belongs_to 여분의 관계를 정의함으로써 : 상점을, 당신은 정보를 액티브을주는이 조인을 완료해야합니다.

  2. ==============================

    2.당신은 액티브 :: EagerLoadPolymorphicError을 얻는 경우에 다형성 협회 만 프리로드에서 지원하는 경우 eager_load을 부르기로 결정 포함 때문입니다. 그것은 여기에 문서입니다 : http://api.rubyonrails.org/v5.1/classes/ActiveRecord/EagerLoadPolymorphicError.html

    당신은 액티브 :: EagerLoadPolymorphicError을 얻는 경우에 다형성 협회 만 프리로드에서 지원하는 경우 eager_load을 부르기로 결정 포함 때문입니다. 그것은 여기에 문서입니다 : http://api.rubyonrails.org/v5.1/classes/ActiveRecord/EagerLoadPolymorphicError.html

    그래서 항상 다형성 연관들에 대해 사전로드를 사용합니다. 이것에 대한 하나주의해야 할 점은있다 : 당신이 어디에 절에서 다형성 assocition 쿼리 할 수 ​​없습니다 (다형성 협회가 여러 테이블을 나타 내기 때문에, 의미가 있습니다.)

  3. ==============================

    3.

    @reviews = @user.reviews.includes(:user, :reviewable)
    .where('reviewable_type = ? AND reviewable.shop_type = ?', 'Shop', 'cafe').references(:reviewable)
    

    당신이 SQL 조각을 사용하는 경우, 참조는 협회에 가입하는 것이 필요하다.

  4. ==============================

    4.우수 상단의 대답은, 당신은 또한 지정할 수 있습니다 추가로 : 어떤 이유로 당신이 사용하는 쿼리가 모델의 테이블을 제외하고는 정의되지 않은 테이블 오류를 얻는 경우 협회에 있습니다.

    우수 상단의 대답은, 당신은 또한 지정할 수 있습니다 추가로 : 어떤 이유로 당신이 사용하는 쿼리가 모델의 테이블을 제외하고는 정의되지 않은 테이블 오류를 얻는 경우 협회에 있습니다.

    그래서 같이 :

    belongs_to :shop, 
               foreign_key: 'reviewable_id', 
               conditions: "reviews.reviewable_type = 'Shop'",
               include: :reviews
    

    (가)없이 : 옵션을 포함 당신은 단지 위의 예에서 협회 review.shop에 액세스하는 경우 협회는 상점에서 선택을 할 것이기 때문에, 당신은 (레일 3에 4를 테스트하지 않음) UndefinedTable 오류가 발생합니다 WHERE shop.id = 1 AND (reviews.review_type = '상점').

    : 포함 옵션은 대신 가입 강제로. :)

  5. from https://stackoverflow.com/questions/16123492/eager-load-polymorphic by cc-by-sa and MIT license