मेरा अनुमान है कि आपके मॉडल इस तरह दिखते हैं:
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
चूंकि यह आपको संबंधित क्षेत्रों द्वारा क्वेरी करने के अलावा उत्सुकता से लोड करने की अनुमति देता है।
कारण यह है कि यह आवश्यक है कि ActiveRecord अकेले समीक्षा के आधार पर एक जॉइन नहीं कर सकता है, क्योंकि कई टेबल्स जॉइन के दूसरे सिरे का प्रतिनिधित्व करते हैं, और SQL, जहाँ तक मुझे पता है, आपको स्टोर किए गए मान द्वारा नामित तालिका में शामिल होने की अनुमति नहीं देता है। एक कॉलम में। अतिरिक्त संबंध को परिभाषित करके 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)