14

Sfondo

Ho un'applicazione di rotaia con associazioni profondamente annidate.Associazioni di carico Eager con serializzatori di modelli attivi

      .-< WorkPeriod 
Timecard -< Week -< Day -<--< Subtotal 
          `-< Adjustment 

-< (has many) 

sto usando Active Model Serializer per costruire l'API.

Sul lato client, voglio caricare un segnaposto e tutte le sue associazioni in un colpo solo.

Attualmente il mio serializzatori simile a questa,

class TimecardSerializer < ActiveModel::Serializer 
    embed :ids, include: true 
    has_many :weeks 
end 
class WeekSerializer < ActiveModel::Serializer 
    embed :ids, include: true 
    has_many :days 
end 
# ... etc ... 

Problema

Questa tutte le opere trovano, tranne che nulla viene ansioso-caricato. Quindi finisce per fare molte chiamate al database per ogni richiesta. Per ogni settimana, fa una richiesta separata per i giorni di quella settimana. E per ogni giorno, fa una richiesta separata per i suoi periodi di lavoro, subtotali e aggiustamenti.

risposta

9

Una soluzione è definire il proprio metodo weeks su TimecardSerializer. Da lì puoi .includes() tutte le associazioni che desideri caricare.

Tutte le query verranno ancora visualizzate nel registro ma la maggior parte sarà una query memorizzata nella cache invece di una reale.

+1

Questo va bene per il caricamento di una singola risorsa, ma non funzionerà se questo serializzatore viene utilizzato per restituire un elenco di 'Timecard's. In particolare, le 'settimane' non saranno caricate con entusiasmo, anche se le associazioni di' settimane' 'saranno. – hjdivad

8

Ho avuto un problema simile. L'ho risolto nel mio controller. Mi piace l'idea di metterlo nel serializzatore, ma averlo nel controller cattura anche il problema di n + 1 settimane creato da ArraySerializer.

Timecard.find(params[:id]).includes(weeks: [{ days: [:sub_totals, :work_periods, :adjustments] }]) 

e

Timecard.includes(weeks: [{ days: [:sub_totals, :work_periods, :adjustments] }]) 

dovrebbe caricare ora ansiosi e limitare la query a soli sei colpi db.