আগ্রহী লোড পলিমারফিক ic


104

রেল ৩.২ ব্যবহার করে, এই কোডটিতে কী দোষ আছে?

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

এটি এই ত্রুটিটি উত্থাপন করে:

বহুগঠিত সমিতি অধীর আগ্রহে লোড করা যায় না: পর্যালোচনাযোগ্য

আমি যদি reviewable.shop_type = ?শর্তটি সরিয়ে ফেলি তবে এটি কাজ করে।

কীভাবে reviewable_typeএবং reviewable.shop_type(যা আসলে shop.shop_type) এর ভিত্তিতে আমি ফিল্টার করতে পারি ?

উত্তর:


207

আমার অনুমান যে আপনার মডেলগুলি দেখতে এমন:

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

আপনি বিভিন্ন কারণে এই ক্যোয়ারীটি করতে অক্ষম।

  1. অ্যাক্টিভেকর্ড অতিরিক্ত তথ্য ছাড়াই যোগদানটি তৈরি করতে অক্ষম।
  2. পর্যালোচনা নামক কোনও টেবিল নেই

এই সমস্যাটি সমাধান করার জন্য আপনাকে 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যেহেতু এটি আপনাকে সংশ্লিষ্ট ক্ষেত্রগুলির দ্বারা অনুসন্ধান করার পাশাপাশি উত্সাহী লোড দেওয়ার অনুমতি দেয়।

এটি প্রয়োজনীয় হওয়ার কারণটি হ'ল এক্টিভেকর্ড একা পর্যালোচনাযোগ্য ভিত্তিতে একটি জোড় তৈরি করতে পারে না, যেহেতু একাধিক টেবিলগুলি যোগটির অন্য প্রান্তকে উপস্থাপন করে, এবং এসকিউএল, যতদূর আমি জানি, সঞ্চিত মান অনুসারে আপনাকে একটি সারণীতে যোগদান করতে দেয় না একটি কলামে। অতিরিক্ত সম্পর্কটি সংজ্ঞায়িত করে belongs_to :shop, আপনি অ্যাক্টিভেকর্ডটিকে যোগদানটি সম্পূর্ণ করার জন্য প্রয়োজনীয় তথ্য দিচ্ছেন।


6
আসলে আমি আরও কিছু না বলে এটি ব্যবহার করে শেষ করেছি:@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)
ভিক্টর

1
কারণ :reviewableএটি Shop। ফটোগুলি শপের অন্তর্গত।
ভিক্টর

6
Rails4 এ কাজ করেছে, তবে একটি অবচয় হুঁশিয়ারি দেবে, এতে বলা হয়েছে has_many: স্প্যাম_কমেন্টস, -> spam যেখানে স্প্যাম: সত্য}, শ্রেণি নাম: 'মন্তব্য' style সুতরাং রেল 4 এ, মালিকানাধীন হবে: শপ, -> {যেখানে ("রিভিউস.রিভিউযোগ্য_ টাইপ = 'শপ'") foreign, বিদেশী_কি: 'পর্যালোচনা_আইডি'। লিজ এক যেখানে সংজ্ঞা।
রেইকিন

49
বিদেশী টাইপও রয়েছে, যা একই সমস্যার জন্য আমার পক্ষে কাজ করেছে:belongs_to :shop, foreign_type: 'Shop', foreign_key: 'reviewable_id'
A5308Y

14
reviewsসংযুক্ত shopকোডটি ব্যবহার করে উত্সাহী লোড সহ লোড করার Review.includes(:shop) সময় যুক্ত_তার সংজ্ঞা belongs_to :shop, -> { where(reviews: {reviewable_type: 'Shop'}) }, foreign_key: 'reviewable_id' ত্রুটি বলছে missing FROM-clause entry for table "reviews"। আমি নীচের পদ্ধতিতে_ সম্পর্কিত সংজ্ঞাটি আপডেট করে এটি স্থির করেছি: belongs_to :shop, -> { joins(:reviews) .where(reviews: {reviewable_type: 'Shop'}) }, foreign_key: 'reviewable_id'
জিগনেশ গোহেল

12

আপনি যদি একটি অ্যাক্টিভেকর্ড :: ইজারলোয়াডপলিমারফিক এরির পান তবে এটি includesকল করার সিদ্ধান্ত নিয়েছে eager_loadযখন পলিমারফিক অ্যাসোসিয়েশনগুলি কেবলমাত্র সমর্থন করে preload। এটি এখানে ডকুমেন্টেশনে রয়েছে: http://api.rubyonrails.org/v5.1/class/ActiveRecord/EagerLoadPolymorphicError.html

তাই সর্বদা preloadপলিমারফিক সংঘের জন্য ব্যবহার করুন । এর জন্য একটি সাবধানবাণী রয়েছে: আপনি যেখানে পলিমর্ফিক সংশ্লেষটি জিজ্ঞাসা করতে পারবেন না যেখানে ক্লজগুলি (যা বোঝায় যেহেতু বহুকোষী সমিতি একাধিক সারণী উপস্থাপন করে))


আমি দেখতে পাচ্ছি যে এটি একটি পদ্ধতি যা গাইডগুলিতে নথিভুক্ত নয়: গাইডস.আরবিওনরইলস.আর.২
এমএসসি

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

আপনি যখন WHERE এর সাথে এসকিউএল টুকরা ব্যবহার করছেন তখন আপনার সমিতিতে যোগ দেওয়ার জন্য রেফারেন্সগুলি প্রয়োজনীয়।


0

শীর্ষে উত্তর হিসাবে সংযোজন হিসাবে, যা দুর্দান্ত, আপনি সমিতিটিতেও উল্লেখ করতে পারেন :includeযদি কোনও কারণে আপনি যে প্রশ্নটি ব্যবহার করছেন সেটি মডেলের টেবিলটি অন্তর্ভুক্ত না করে এবং আপনি অনির্ধারিত টেবিলের ত্রুটিগুলি পেয়ে যাচ্ছেন।

তাই ভালো:

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

:includeবিকল্পটি ব্যতীত review.shop, আপনি যদি উপরের উদাহরণে কেবল অ্যাসোসিয়েশন অ্যাক্সেস করেন তবে আপনি একটি অপরিজ্ঞাতযোগ্য ত্রুটি পাবেন (4 টি নয়, রেল 3 এ পরীক্ষিত) কারণ সমিতিটি করবে SELECT FROM shops WHERE shop.id = 1 AND ( reviews.review_type = 'Shop' )

:includeবিকল্প একটি পরিবর্তে JOIN বাধ্য করা হবে। :)


5
অজানা কী: শর্তসমূহ। বৈধ কীগুলি হ'ল:: শ্রেণি_নাম,: শ্রেণি,: বিদেশী_কি,: বৈধকরণ,: অটোসোভ,: নির্ভরশীল,: প্রাথমিক_কি,: বিপরীত_,: প্রয়োজনীয়,: বিদেশী_প্রকার,: বহুকোষ,: স্পর্শ,: পাল্টা_ক্যাচ
বেঙ্গালা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.