مجموعة روبي/ريلز إلى المجموعة
-
09-06-2019 - |
سؤال
لدي جدولان مرتبطان بجدول ربط - وهذا مجرد رمز زائف:
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