2014-11-14 15 views
7

Come posso accedere ai dettagli dell'utente che sollevano la richiesta da un gancio modellorichiesta di accesso intestazioni da BeforeSave Modello Hook

Comment.beforeSave = function(next,com) { 
//Want to add 2 more properties before saving 
com.added_at = new Date();  
com.added_by = //How can i set the user id here ?? 
//In case of a Remote hook i have ctx in param and i can get user id like this  ctx.req.accessToken.userId; But in Model Hook how can i do the same?  
next();  
}; 

Esiste un modo per fare questo? Ho provato con il gancio remoto per l'articolo principale nel modo

MainItem.beforeRemote('**', function(ctx, user, next) { 
if(ctx.methodString == 'leave_request.prototype.__create__comments'){  
    ctx.req.body.added_by = ctx.req.accessToken.userId;  
    ctx.req.body.added_at = new Date();       
    console.log("Added headers as .."+ctx.req.body.added_by); 
}  
else{ 
    ctx.req.body.requested_at = new Date(); 
    ctx.req.body.requested_by = ctx.req.accessToken.userId; 
    console.log("Added header @ else as .."+ctx.req.body.requested_by); 
} 
next(); 

});

e ho la log della console correttamente una volta faccio richiesta da esploratore, ma Ma l'esploratore mi restituiscono sempre l'errore

"errore": { "name": "ValidationError", "status": 422, "messaggio": "L'istanza comment non è valido dettagli: added_by non può essere vuoto; added_at non può essere vuoto..", "statusCode": 422, "dettagli": { "contesto" : "commento", "codici": { "added_by": [ "presenza" ], "added_at": [ "presenza" ] }, "messaggi": { "added_by": [ "non può essere vuoto" ], "added_at": [ "può 't be blank' ] } }, "stack": "ValidationError: l'istanza comment non è valida. Dettagli: added_by non può essere vuoto; added_at non può essere vuoto. \ N " }}

e il mio modello è come

"properties": { 
"body": { 
    "type": "string", 
    "required": true 
}, 
"added_by": { 
    "type": "number", 
    "required": true 
}, 
"added_at": { 
    "type": "date", 
    "required": true 
}, 
"leave_request_id":{ 
    "type": "number", 
    "required": true 
} 

}

risposta

9

Sembra che non sia possibile aggiornare il modello correlato semplicemente ignorando ctx.req.body. Invece di dovresti ignorare ctx.args.data - sembra che questo parametro ctx sia usato per inizzare il modello correlato.

Così sarà simile a quanto segue:

MainItem.beforeRemote('**', function(ctx, user, next) { 
    if(ctx.methodString == 'leave_request.prototype.__create__comments'){ 
    ctx.args.data.added_by = ctx.req.accessToken.userId;  
    ctx.args.data.added_at = new Date();       
    console.log("Added headers as .."+ctx.args.data.added_by); 
    }  
    else{ ... } 
    next(); 
2

I ganci beforeRemote eseguire prima che il modello ganci, in modo da poter aggiungere l'userId al corpo della richiesta.

Comment.beforeRemote('**', function (ctx, unused, next) { 
    var userId = ctx.req.accessToken.userId; 
    if (ctx.methodString == 'Comment.create' || ctx.methodString == 'Comment.updateAttributes') { 
     ctx.req.body.userId = userId; 
    } 
    next(); 
}); 

si potrebbe desiderare di controllare quali si adattano meglio methodstring.

+0

Il mio modello di commento non è esposto direttamente all'API. Quindi beforeRemote non eseguirà per questo. Il mio endpoint è MainItem//Comment. Quindi primaRemota verrà eseguito solo per MainItem –

+0

In tal caso, sarà necessario impostare il gancio sul modello MainItem e provare a memorizzare l'ID utente in un globale o nelle impostazioni di commento. Ciò non è ottimale e potrebbe causare errori nelle richieste simultanee. Mi dispiace per quello. – amenadiel

+0

Ora ho una domanda edita, puoi aiutarmi ora? –

1

Di fronte allo stesso problema, ho utilizzato la funzionalità nodo expiremantal domain (destinata alla gestione degli errori).

Salvataggio oggetto richiesta in arrivo:

// -- Your pre-processing middleware here -- 
app.use(function (req, res, next) { 
    // create per request domain instance 
    var domain = require('domain').create(); 

    // save request to domain, to make it accessible everywhere 
    domain.req = req; 
    domain.run(next); 
}); 

Successivo gancio modello all'interno si ha accesso a oggetto req, che viene creato per ogni connessione:

process.domain.req 

anche StrongLoop team ha aggiunto context propagation (sulla base di continuation-local-storage), ma non è ancora stato documentato.

0

Se assumiamo che vi sia una relazione commenti di utente -> commento, si può anche provare il metodo relazione POST /users/{user_id}/comments che popolare il foreignId (che può essere added_by).

Un'altra cosa è added_at. Per quanto ho capito, l'hook di validazione viene attivato prima di creare hook. Significa che la validazione fallirà, poiché questo campo è contrassegnato come richiesto in un modello. La domanda è se questo campo debba essere contrassegnato come richiesto, poiché è impostato dal server e non deve essere impostato dal client dell'API.

1

Ho risolto questo con l'aggiunta di middleware per l'analisi del corpo. Negli middleware.js ho scritto il seguente codice:

... 
"parse": { 
    "body-parser#json": {}, 
    "body-parser#urlencoded": {"params": { "extended": true }} 
}, 
... 

Inoltre, nelle server.js ho aggiunto la richiedono per il corpo parser e multer:

var loopback = require('loopback'); 
... 
var bodyParser = require('body-parser'); 
var multer = require('multer'); 
... 

app.use(bodyParser.json()); // application/json 
app.use(bodyParser.urlencoded({ extended: true })); // application/x-www-form-urlencoded 
app.use(multer()); // multipart/form-data 
... 

Quindi aggiungere le dipendenze nel pacchetto .json

"body-parser": "^1.12.4", 
"multer": "^0.1.8" 

Ora si possono fare cose come la seguente nei /models/user.js (per qualsiasi modello)

user.beforeRemote('create', function(ctx, unused, next) { 
    console.log("The registered user is: " + ctx.req.body.email); 
    next(); 
    }); 

Spero che questo aiuti! :)

Problemi correlati