2014-04-05 37 views
7

ho i seguenti tre modelli unirsi-rapportoRails Partecipa Modello selezionare le colonne comuni

class Book < ActiveRecord::Base 
    has_many :contributions, :dependent => :destroy 
    has_many :contributors, :through => :contributions 
end 

class Contributor < ActiveRecord::Base 
    has_many :contributions, :dependent => :destroy 
    has_many :books, :through => :contributions do 
    def this_is_my_contribution(book, join_attrs) 
     Contribution.with_scope(:create => join_attrs) {self << book} 
    end 
    end 
end 

class Contribution < ActiveRecord::Base 
    belongs_to :book 
    belongs_to :contributor 
end 

Poi, dopo l'inserimento di record nel Contributo unirsi modella, ho deciso che voglio fare una domanda su questo modello per recuperare tutte le libri e nomi di collaboratori come una query risultato come il seguente SQL equivalente

SELECT Contributions.*, Contributors.name, Books.name from Contributions 
INNER JOIN Contributors ON Contributors.id = Contributions.contributors_id 
INNER JOIN Books ON Books.id = Contributions.books_id 

Ma in console irb, quando ho scritto questo,

Contribution.joins(:contributor, :book).select("contributors.name, books.name, 
    contributions.*") 

ottengo il seguente output invece

Contribution Load (0.8ms) SELECT contributors.name, books.name, contributions.* FROM 
"contributions" INNER JOIN "contributors" ON "contributors"."id" = 
"contributions"."contributor_id" INNER 
JOIN "books" ON "books"."id" = "contributions"."book_id"                                   
=> #<ActiveRecord::Relation [#<Contribution id: 1, book_id: 1, contributor_id: 1, role: 
"author", created_at: "2014-04-04 00:19:15", updated_at: "2014-04-04 00:19:15">, # 
<Contribution id: 2, book_id: 2, contributor_id: 2, role: "Author", created_at: "2014- 
04-05 06:20:34", updated_at: "2014-04-05 06:20:34">]> 

non ho ricevuto alcun nome del libro e il nome del collaboratore in base alle chiavi INNER JOIN stranieri.

Non riuscivo a capire come l'istruzione SQL di RAILS si sbagliava molto quando questo è ciò che voglio intensamente.

Che cosa comprendo pienamente?

risposta

5

I modelli di rails sono mappati con le tabelle associate, quindi dopo aver interrogato questo modello restituisce oggetti oggetto che in questo caso è il modello Contribution che non ha altri attributi di modelli, per ottenere ciò che si desidera è necessario scrivere la query come

contributions = Contribution.joins(:contributor, :book).select("contributors.name 
    as c_name, books.name as b_name, contributions.*") 

risultato restituito sarà serie di contributi e si potrebbe ottenere il nome del libro dal risultato attributo b_name come

contributions.last.b_name 

Nota: a seconda di come si intende utilizzare i risultati di query si deve c hoose tra joins e includes si poteva leggere Here

+0

Grazie Sat's. Mi scuso per la risposta tardiva. Non ho la possibilità di provare il codice qui sopra. Ma dopo aver letto il link che hai fornito sopra, sta diventando più chiaro per me perché è necessario seguire questi passaggi. Grazie ancora! – awongCM

0

Sì, nella risposta di interrogazione è solito vedere qualsiasi nome libri, tuttavia se risultato [0] .book.name, si vedrà il nome del libro. Non è visibile solo nel risultato visualizzato ma puoi ottenerlo semplicemente accedendo.

Come accennato, è possibile utilizzare include, in modo che non esegua query aggiuntive quando si accede alla tabella del libro, tuttavia in join effettuerà chiamate DB aggiuntive per ogni accesso alla tabella del libro.

+0

Grazie per quello. Anche se devo ammettere. Non ero così a mio agio nel vedere come il mio codice non poteva recuperare i risultati come gli avevo detto esplicitamente di fare prima di menzionare sull'uso di join, selezioni e include. Ci provo per il mio prossimo progetto. Saluti! – awongCM

Problemi correlati