2016-02-28 18 views
9

Vorrei ottenere typeName attributo come parte del modello baffle, senza recuperarlo da baffleType in modo esplicito ogni volta.Recupera sempre dai modelli correlati in Bookshelf.js

le seguenti opere per me, ma sembra che withRelated caricherà le relazioni se baffle modello è direttamente inverosimile, non dalla relazione:

let baffle = bookshelf.Model.extend({ 
    constructor: function() { 
     bookshelf.Model.apply(this, arguments); 

     this.on('fetching', function(model, attrs, options) { 
      options.withRelated = options.withRelated || []; 
      options.withRelated.push('type');   
     }); 
    }, 

    virtuals: { 
     typeName: { 
      get: function() { 
       return this.related('type').attributes.typeName; 
      } 
     } 
    }, 
    type: function() { 
     return this.belongsTo(baffleType, 'type_id'); 
    } 
}); 

let baffleType = bookshelf.Model.extend({}); 

Qual è il modo corretto di farlo?

risposta

3

Questa domanda è super vecchia, ma sto rispondendo comunque.

Ho risolto questo aggiungendo solo una nuova funzione, fetchFull, che mantiene le cose piuttosto ASCIUTTE.

let MyBaseModel = bookshelf.Model.extend({ 
    fetchFull: function() { 
    let args; 
    if (this.constructor.withRelated) { 
     args = {withRelated: this.constructor.withRelated}; 
    } 
    return this.fetch(args); 
    }, 
}; 

let MyModel = MyBaseModel.extend({ 
    tableName: 'whatever', 
    }, { 
    withRelated: [ 
     'relation1', 
     'relation1.related2' 
    ] 
    } 
); 

Poi ogni volta che stai interrogando, è possibile chiamare Model.fetchFull() per caricare tutto, o nei casi in cui non si vuole prendere un calo di prestazioni, si può ancora ricorrere a Model.fetch().

+0

Grazie, non è mai troppo tardi. – estus

7

L'emissione su repo è correlata all'evento Fetched, tuttavia l'evento Fetching funziona correttamente (v0.9.2).

Quindi, solo per esempio, se si dispone di un terzo modello come

var Test = Bookshelf.model.extend({ 
    tableName : 'test', 
    baffleField : function(){ 
     return this.belongsTo(baffle) 
    } 
}) 

e poi fare Test.forge().fetch({ withRelated : ['baffleField']}), fetching evento sul deflettore verrà generato. Tuttavia ORM non includerà type (sub modello correlati) a meno che non espressamente dice di farlo

Test.forge().fetch({ withRelated : ['baffleField.type']}) 

Tuttavia vorrei try to avoid questo se sta facendo N Query per N records.

UPDATE 1

stavo parlando stessa cosa che si stava facendo sul fetching evento come

fetch: function fetch(options) { 
    var options = options || {} 
    options.withRelated = options.withRelated || []; 
    options.withRelated.push('type');  
    // Fetch uses all set attributes. 
    return this._doFetch(this.attributes, options); 
} 

in model.extend. Tuttavia, come puoi vedere, questo potrebbe non riuscire nelle modifiche version.

+0

Buon punto per il "recupero", grazie. Quindi, la modifica di 'options.withRelated' è l'unica opzione qui se voglio mantenere la logica di business DRY e saltare' {withRelated: ...} 'su tutte le chiamate' fetch() '? Le prestazioni non sono critiche in questa parte dell'app. – estus

+0

@estus Penso di sì. Comunque ho usato il sequelize per un po ', quindi non posso esserne sicuro. Un altro modo di fare la stessa cosa è '' 'overriding''' (non una buona parola per JS) metodo di recupero in' '' model.extend'''. Tuttavia, lavorare con l'evento '' 'fetching''' è più un modo di bookshelf di farlo. Sovrascrivere un metodo è più pulito, ma potrebbe non riuscire con gli upgrade/downgrade della versione. – Satyajeet

+0

Sembra che il 'recupero' sia attivato ma nessuna relazione nidificata viene caricata quando 'baffle' è caricato come una relazione, quindi 'prelievo' dovrebbe essere specificato in ciascun modello principale. Potresti aggiungere un esempio per overriden 'fetch'? Dovrebbe essere qualcosa come 'fetch: function (... args) {return bookshelf.Model.prototype.fetch.bind (this) (... args)}'? – estus