내 생각에는 모델이 다음과 같이 보입니다.
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
여러 가지 이유로 해당 쿼리를 수행 할 수 없습니다.
- ActiveRecord는 추가 정보없이 조인을 빌드 할 수 없습니다.
- 검토 가능이라는 표가 없습니다.
이 문제를 해결하기 위해 명시 적 사이의 관계를 정의해야 Review하고 Shop.
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'})
테이블 이름은 shops이고는 아닙니다 reviewable. 데이터베이스에 검토 가능이라는 테이블이 없어야합니다.
나는이 쉽고 명시 적으로 정의하는 것보다 더 유연한 생각하는 join사이 Review와 Shop는 관련 분야에서 쿼리에 추가 열망로드 할 수 있기 때문에.
이것이 필요한 이유는 여러 테이블이 조인의 다른 쪽 끝을 나타내며 SQL은 저장된 값으로 명명 된 테이블을 조인하는 것을 허용하지 않기 때문에 ActiveRecord는 검토 가능만으로 조인을 작성할 수 없기 때문입니다. 열에. 추가 관계를 정의 belongs_to :shop함으로써 ActiveRecord에 조인을 완료하는 데 필요한 정보를 제공하게됩니다.
@reviews = @user.reviews.joins("INNER JOIN shops ON (reviewable_type = 'Shop' AND shops.id = reviewable_id AND shops.shop_type = '" + type + "')").includes(:user, :reviewable => :photos)