2012-11-20 14 views
5

che sto cercando di recuperare i dati in un formato nidificato tra le seguenti due tabelle (in SQLite)Recupero record annidati in Sequel

DB = Sequel.sqlite('database.sqlite') 

DB.create_table? :artists do 
    primary_key  :id 
    String   :name 
end 

DB.create_table? :albums do 
    primary_key  :id 
    String   :title 
    foreign_key  :artist_id, 
        :artists, 
        :key => :id 
end 

artists = DB[:artists] 
albums = DB[:albums] 

id1 = artists.insert(:name => 'Mike') 
id2 = artists.insert(:name => 'John') 

albums.insert(:title => 'Only You', :artist_id => id1) 
albums.insert(:title => 'Only Us', :artist_id => id1) 
albums.insert(:title => 'Only Me', :artist_id => id2) 

L'uscita Sto cercando di ottenere -

[ 
    { 
    :id => 1, 
    :name => 'Mike' 
    :albums => [ 
     { 
     :id => 1, 
     :title => 'Only You' 
     }, 
     { 
     :id => 2, 
     :title => 'Only Us' 
     } 
    ] 
    }, 
    { 
    :id => 2, 
    :name => 'John' 
    :albums => [ 
     { 
     :id => 3, 
     :title => 'Only Me' 
     } 
    ] 
    } 
] 

ho provato carico 'ansioso' -

class Artist < Sequel::Model(:artists) 
    one_to_many :db[:albums], :key => :artist_id 
end 

class Album < Sequel::Model(:albums) 
    many_to_one :artist, :key => :artist_id 
end 


Artist.eager(:albums).all{ |a| p a } 

Ma che non ha funzionato.

Qualcuno può indicarmi la giusta direzione?

risposta

4

Artist.eager(:albums).all fa avidamente caricare i dischi, ma {|a| p a} non sta per mostrare gli album (come Sequel::Model#inspect mostra solo i valori per il modello attuale, non tutti gli oggetti associati). Usa {|a| p [a, a.albums]} per vedere che gli album sono già stati caricati.

Se si desidera produrre l'hash che hai descritto:

Artist.eager(:albums).all.map do |a| 
    a.values.merge(:albums=>a.albums.map{|al| al.values}) 
end 
+0

Grazie per avermi permesso di conoscere il motivo per cui io non stavo vedendo il 'album'! – globetrotter

2

È possibile aggiungere un metodo per artista a emetterlo il modo desiderato

class Artist < Sequel::Model(:artists) 
    one_to_many :albums, :key => :artist_id 

    def my_hash 
    to_hash.merge!(
     { 
      :albums => albums.map{|a| 
       a.to_hash.reject!{ |k,v| 
        k==:artist_id 
       } 
      } 
     } 
    ) 
    end 
end 

class Album < Sequel::Model(:albums) 
    many_to_one :artist, :key => :artist_id 
end 

records = Artist.all.map{ |a| a.my_hash } 
p records 

Invece di usare reject! sarebbe più pulito per aggiungere un metodo my_hash l'album per restituire un hash senza la :artist_id, ma hai un'idea. Questo uscite:

[ 
    { 
    :albums=>[ 
     { 
     :title=>"Only You", 
     :id=>1 
     }, 
     { 
     :title=>"Only Us", 
     :id=>2 
     } 
    ], 
    :name=>"Mike", 
    :id=>1 
    }, 
    { 
    :albums=>[ 
     { 
     :title=>"Only Me", 
     :id=>3 
     } 
    ], 
    :name=>"John", 
    :id=>2 
    } 
]