2012-02-27 13 views
5

Estoy intentando crear una ruta para que los usuarios puedan verificar los perfiles de otros usuarios. Sin embargo, quiero que se acceda a estos perfiles a través de 2 URL diferentes /profile/nickname y /profile/id para que se pueda acceder a un perfil mediante el nombre de usuario o la identificación del usuario. He probado el siguiente código:

app.get("/profile/:id", function(req, res) { 

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": req.params.id }] }, function(err, user) { 
    if(user) 
    { 
     res.render('users/profile.jade', { 
     locals: { 
      currentUser: user, 
      title: user.nickname +"'s Profile", 
      jsf:[], 
     } 
     }); 
    } 
    else 
    { 
     res.render('404.jade', { 
      status: 404, 
      title: 'Page Not Found', 
       jsf: [] 
     }); 
    } 
}); 
}); 

El problema es que parece que sólo se está trabajando con el ello y no con el apodo, lo que significa que si ACCES trabajan /profile/4f4ae474546708b219000005 cosas, pero si accedo /profile/mmellad que es el dado el apodo para ese usuario, obtengo la página 404.

Existe también una cosa más que me di cuenta de que funciona bien para los apodos, que está cambiando la consulta de

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": req.params.id }] } 

a

User.findOne({ "nickname": req.params.id } } 

en este caso /profile/mmellado funciona bien, pero el uso de la la identificación del usuario obviamente no.

¿Cuál sería la forma correcta de hacerlo? Estoy pensando que puedo estar usando un enfoque equivocado.

Otra cosa a mencionar es que si intento el siguiente código en la consola mongo, que funciona bien, así:

x = db.users.findOne({ $or: [ {nickname:"mmellado"}, {_id:ObjectId("4f4ae474546708b219000005")} ]}) 

He probado que el código insertando el apodo derecho y un _id mal, entonces probados con un apodo incorrecto y _id derecho. En ambos casos, x terminó conteniendo el objeto para el registro que necesitaba.

Creo que puedo arreglarlo con una ruta adicional, pero soy nuevo en Node.js y Express all together así que no estoy seguro de cuál sería el enfoque adecuado.

Gracias!

+0

¿Qué versión de mongo estás usando? –

+0

versión Mongo es la siguiente: Marcos-Mellados Imac-2: ~ $ marcos mongod --version versión db v2.0.2, la versión 4.5 pdfile Lun Feb 27 Versión 02:48:11 git: 514b122d308928517f5841888ceaa4246a7f18e3 –

Respuesta

4

¿Has probado esto en la consola: x = db.users.findOne({ $or: [ {nickname:"mmellado"}, {_id:ObjectId("mmellado")} ]}). Verás un error incluso si el apodo coincide porque primero intenta convertir "mmellado" en un ObjectId y falla. Esta podría ser la razón por la cual su página falla al usar un apodo.

No conozco los componentes internos del mongodb node.js, pero probablemente intente convertir el argumento internamente en ObjectId antes de consultar el campo "_id" (y fallar si no es válido). No revisé esto, así que pruébalo. También intente verificar el objeto err en la devolución de llamada. Si ese es el problema, una forma de resolver esto es verificar que el argumento sea ObjectId válido antes de consultar, por ejemplo, crear ObjectId fuera de él y detectar excepciones si falla. Algo como esto (no probado): los valores _id

try { 
    var objectId = createObjectId(req.params.id); // Create this function yourself 
    User.findOne({ "_id": objectId }, callbackFunction); 
} catch (err) { 
    // Fall back to using nickname 
    User.findOne({ "nickname": req.params.id }, callbackFunction); 
} 
+0

Probé imprimiendo el código de error en el momento de la consulta. Esto es lo que obtengo: [Error: ObjectId no válido], Mi intento es que cuando trato de usar Finch como un param, y la condición pasa por la parte _id, dado que la cadena dada no es un ObjectId válido, la consulta se rompe, devolviendo un error ... por lo tanto, no da el resultado, incluso si parte de la consulta funcionó ... alguna idea sobre cómo solucionar esto? –

+0

@MarcosMellado Eso parece apoyar mis pensamientos. He propuesto una solución en mi publicación, la he modificado para agregar un código de muestra para que quede más clara. – Lycha

+0

En realidad, he llegado a una solución MUY similar, haré los cambios adecuados para que funcione con el try catch y le deje saber si funcionó :) –

0

por defecto son 12 bytes hashes binarios por lo que primero hay que convertir la cadena en binario antes de enviar la consulta utilizando ObjectID.createFromHexString así:

var id = ObjectID.createFromHexString(idHex); 

Luego use el id en su consulta.

El código debería ser algo como esto:

User.findOne({ $or : [{ "nickname": req.params.id },{ "_id": ObjectID.createFromHexString(req.params.id) }] }, function(err, user) { ........ 

Saludos Finch !!!

+0

¿Cómo definiría el ObjectId? En este momento tengo mongoose = require ('mangosta'), \t \t ObjectID = mongoose.Schema.ObjectId, –

+0

Ignore el último comentario, el problema con su enfoque es, en el momento de enviar un apodo como parámetro y pasarlo a través de la función createFromHexString, arroja el siguiente error: Error: el argumento pasado debe ser una única cadena de 12 bytes o una cadena de 24 caracteres hexadecimales en formato hexadecimal (asumiendo que el apodo es pinzón, por ejemplo) –

+0

Ture, intenta convertir primero su cadena (Finch) en una Cadena Hexagonal usando: var hexString = nickname.toHexString(); - luego pasa eso como argumento para crear tu objectID – user313551

Cuestiones relacionadas