سؤال

لدي جدولان مرتبطان بجدول ربط - وهذا مجرد رمز زائف:

Library
Book
LibraryBooks

ما يجب علي فعله هو أنه إذا كان لدي معرف مكتبة، فأنا أرغب في الحصول على جميع المكتبات التي توجد بها جميع الكتب الموجودة في هذه المكتبة.

لذا، إذا كان لدي المكتبة 1، والمكتبة 1 تحتوي على الكتب A وB، والكتب A وB موجودة في المكتبات 1 و2 و3، فهل هناك طريقة أنيقة (سطر واحد) للقيام بذلك في Rails؟

كنت افكر:

l = Library.find(1)
allLibraries = l.books.libraries

ولكن لا يبدو أن هذا يعمل.اقتراحات؟

هل كانت مفيدة؟

المحلول

l = Library.find(:all, :include => :books)
l.books.map { |b| b.library_ids }.flatten.uniq

لاحظ أن map(&:library_ids) أبطأ من map { |b| b.library_ids } في روبي 1.8.6، وأسرع في 1.9.0.

يجب أن أذكر أيضًا أنه إذا كنت تستخدم :joins بدلاً من include هناك، سيجد المكتبة والكتب ذات الصلة كلها في نفس الاستعلام مما يؤدي إلى تسريع وقت قاعدة البيانات. :joins لن يعمل إلا إذا كانت المكتبة تحتوي على كتب.

نصائح أخرى

ربما:

l.books.map {|b| b.libraries}

أو

l.books.map {|b| b.libraries}.flatten.uniq

إذا كنت تريد كل ذلك في مجموعة مسطحة.

بالطبع، يجب عليك تعريف هذا كطريقة في المكتبة، وذلك لدعم السبب النبيل للتغليف.

إذا كنت تريد إرجاع مصفوفة أحادية البعد من المكتبات، مع إزالة التكرارات.

l.books.map{|b| b.libraries}.flatten.uniq

مشكلة واحدة مع

l.books.map{|b| b.libraries}.flatten.uniq

هو أنه سيتم إنشاء استدعاء SQL واحد لكل كتاب في l.قد يكون النهج الأفضل (على افتراض أنني أفهم مخططك) هو:

LibraryBook.find(:all, :conditions => ['book_id IN (?)', l.book_ids]).map(&:library_id).uniq
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top