Rails 3: selezionare con Include?

Ecco una selezione annidata con include:

@items = Item.where("complete = ?", true).includes( :manufacturer, {:order=>[:supplier, :agent] }) 

Questa è una query di tassazione poiché estrae migliaia di righe di dati da tutte le tabelle incluse sopra.

Come posso ottenere la query per selezionare solo campi specifici?

  • user.name, user.created_at
  • order.created_at
  • Nome del fornitore
  • agent.name
  • nome del produttore

C’è un metodo di selezione in ARel, ma devi usare i nomi di tabella corretti (cioè plurale e fai attenzione se hai modelli polimorfici o se stai usando set_table_name o qualche altra pratica non standard simile)

 @items = Item. select('users.name', 'users.created_at', 'orders.created_at', 'suppliers.name', 'agents.name', 'manufacturers.name'). where(:users => { :fulfilled => true }). includes(:orders => [:supplier, :agent], :manufacturer) 

“Possiamo usare select con joins not include” – @Bhavesh_A_P

Nota:

Come sottolineato da @Bhavesh_A_P sopra, select con includes non produce un comportamento coerente. Sembra che se l’associazione inclusa non restituisce risultati, select funzionerà correttamente, se restituisce risultati, l’istruzione select non avrà alcun effetto. Di fatto, verrà completamente ignorato, in modo tale che la tua istruzione select possa fare riferimento a nomi di tabelle non validi e non verrà prodotto alcun errore. select con i joins produrrà un comportamento coerente.

In realtà non possiamo usare select with includes. Può essere utilizzato solo con join.

Il problema non è risolto includendo una chiamata al metodo ‘select’ nella catena. In un ActiveRecord :: Relation simile che abbiamo creato, chiamare “include” sembra sovrascrivere qualsiasi chiamata a “seleziona”.

 scope :active, where("hired_on < ? AND (separated_on > ? OR separated_on IS NULL)", Time.now, Time.now ) scope :with_role, lambda {|roles| includes(:team_member_roles).where(:team_member_roles => {:role => roles } ) } scope :with_site_code, lambda {|site_codes| includes(:team_member_sites).where(:team_member_sites => {:site_code => site_codes } ) } TeamMember.select("team_members.email, team_members.first_name, team_members.last_name").active.with_site_code(params[:site_code]).with_role(["senior_editing", "senior_and_reg_editing"]) 

Come mostrato, la query seleziona tutte le colonne.

Quando i due ambiti utilizzano “join” anziché “include”, la query funziona: vengono selezionate solo le 3 colonne specificate.

 Item.where("fulfilled = ?", true) .includes({:orders =>[:suppliers, :agents]}, :manufacturers) .select("users.name, users.created_at, orders.created_at, suppliers.name, agents.name"). .order('orders.created_at DESC')