Domanda

Ho due tabelle unite con una tabella di join: questo è solo pseudo codice:

Library
Book
LibraryBooks

Quello che devo fare è se ho l'ID di una biblioteca, voglio ottenere tutte le biblioteche in cui si trovano tutti i libri di questa biblioteca.

Quindi, se ho la Biblioteca 1 e la Biblioteca 1 contiene i libri A e B, e i libri A e B sono nelle Biblioteche 1, 2 e 3, esiste un modo elegante (una riga) per farlo sui binari?

Stavo pensando:

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

Ma questo non sembra funzionare.Suggerimenti?

È stato utile?

Soluzione

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

Notare che map(&:library_ids) è più lento di map { |b| b.library_ids } in Ruby 1.8.6 e più veloce in 1.9.0.

Dovrei anche menzionarlo se lo hai usato :joins invece di include lì, troverebbe la biblioteca e i libri correlati tutti nella stessa query, accelerando i tempi del database. :joins funzionerà tuttavia solo se una biblioteca ha libri.

Altri suggerimenti

Forse:

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

O

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

se vuoi tutto in un array piatto.

Naturalmente, dovresti davvero definirlo un metodo sulla Libreria, in modo da sostenere la nobile causa dell'incapsulamento.

Se si desidera restituire un array unidimensionale di librerie, con i duplicati rimossi.

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

Un problema con

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

è che genererà una chiamata SQL per ogni libro in l.Un approccio migliore (supponendo che io comprenda il tuo schema) potrebbe essere:

LibraryBook.find(:all, :conditions => ['book_id IN (?)', l.book_ids]).map(&:library_id).uniq
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top