2012-02-27 32 views
5

Tôi đang cố gắng tạo tuyến đường để người dùng có thể kiểm tra hồ sơ của người dùng khác. Tuy nhiên, tôi muốn các cấu hình này được gắn thông qua 2 url khác nhau /profile/nickname/profile/id để hồ sơ có thể được truy cập bằng cách sử dụng biệt hiệu hoặc id người dùng của người dùng. Tôi đã thử các mã sau:

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: [] 
     }); 
    } 
}); 
}); 

Vấn đề là, nó có vẻ như nó chỉ được làm việc với các id và không phải với biệt danh, có nghĩa là nếu tôi acces /profile/4f4ae474546708b219000005 mọi thứ làm việc, nhưng nếu tôi truy cập /profile/mmellad đó là đã đặt biệt hiệu cho người dùng đó, tôi nhận được trang 404.

Ngoài ra còn có một điều nữa tôi đã tìm ra rằng hoạt động tốt cho biệt danh, mà là thay đổi các truy vấn từ

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

để

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

trong trường hợp này /profile/mmellado hoạt động tốt nhưng sử dụng id người dùng rõ ràng là không.

Điều gì sẽ là đúng cách để thực hiện việc này? Tôi nghĩ tôi có thể đang sử dụng một cách tiếp cận sai lầm.

Một điều cần đề cập đến được rằng nếu tôi cố gắng đoạn mã sau trong Mongo console, nó hoạt động tốt cũng như:

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

Tôi đã thử nghiệm mã mà bằng cách chèn các nickname phải và một _id sai, sau đó kiểm tra với biệt hiệu sai và phải _id. Trong cả hai trường hợp, x đã kết thúc chứa đối tượng cho bản ghi mà tôi cần.

Tôi nghĩ rằng tôi có thể khắc phục nó bằng một tuyến đường bổ sung, nhưng tôi mới sử dụng Node.js và Express cùng nhau nên tôi không chắc chắn về cách tiếp cận propper sẽ là gì.

Cảm ơn!

+0

Bạn đang sử dụng phiên bản nào của mongo? –

+0

phiên bản Mongo như sau: Marcos-Mellados-iMac-2: ~ marcos $ mongod --version db phiên bản v2.0.2, phiên bản pdfile 4,5 Mon 27 tháng 2 phiên bản 02:48:11 git: 514b122d308928517f5841888ceaa4246a7f18e3 –

Trả lời

4

Bạn đã thử điều này trong bảng điều khiển: x = db.users.findOne({ $or: [ {nickname:"mmellado"}, {_id:ObjectId("mmellado")} ]}). Bạn sẽ thấy một lỗi ngay cả khi biệt hiệu khớp vì trước tiên nó cố gắng chuyển đổi "mmellado" thành một ObjectId và không thành công. Đây có thể là lý do trang của bạn không thành công khi sử dụng biệt hiệu.

Tôi không biết nội bộ trình điều khiển mongodb-node.js, nhưng nó có thể cố chuyển đổi đối số nội bộ thành ObjectId trước khi truy vấn trường "_id" (và không thành công nếu không hợp lệ). Tôi đã không kiểm tra điều này, vì vậy hãy thử nó ra. Ngoài ra hãy thử kiểm tra đối tượng err trên callback. Nếu đó là vấn đề một cách để giải quyết điều này là để kiểm tra là đối số là hợp lệ ObjectId trước khi truy vấn, ví dụ tạo ObjectId ra khỏi nó cho mình và bắt ngoại lệ nếu nó không thành công. Một cái gì đó như thế này (không kiểm tra): giá trị _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

tôi đã cố gắng in mã lỗi tại thời điểm truy vấn. Đây là những gì tôi nhận được: [Lỗi: ObjectId không hợp lệ], Giả định của tôi là khi tôi cố gắng sử dụng Finch làm tham số và điều kiện đi qua phần _id, vì chuỗi đã cho không phải là ObjectId hợp lệ, các ngắt truy vấn, trả về một lỗi ... do đó không cho kết quả ngay cả khi một phần của truy vấn đã làm việc ... bất kỳ ý tưởng về cách làm việc xung quanh điều này? –

+0

@MarcosMellado Điều đó dường như hỗ trợ cho suy nghĩ của tôi. Tôi đã đề xuất giải pháp trong bài viết của mình, tôi đã sửa đổi nó để thêm một số mã mẫu để làm cho nó rõ ràng hơn. – Lycha

+0

Tôi đã thực sự đến một giải pháp RẤT tương tự, tôi sẽ thực hiện các thay đổi thích hợp để nó hoạt động với thử bắt và cho bạn biết nếu nó hoạt động :) –

0

mặc định là 12 byte băm nhị phân, do đó bạn đầu tiên cần phải chuyển đổi chuỗi thành nhị phân trước khi bạn gửi truy vấn sử dụng ObjectID.createFromHexString như thế này:

var id = ObjectID.createFromHexString(idHex); 

Sau đó sử dụng id trong truy vấn của bạn.

Mã của bạn nên tìm một cái gì đó như thế này:

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

Greetings Finch !!!

+0

Bạn định nghĩa ObjectId như thế nào? Ngay bây giờ tôi có mongoose = require ('mongoose'), \t \t ObjectID = mongoose.Schema.ObjectId, –

+0

Bỏ qua nhận xét cuối cùng, vấn đề với cách tiếp cận của anh ấy là, tại thời điểm gửi một biệt danh làm tham số và chuyển nó thông qua hàm createFromHexString, nó ném lỗi tiếp theo: Lỗi: Đối số được truyền vào phải là một chuỗi 12 byte hoặc một chuỗi gồm 24 ký tự hex ở định dạng hex (giả sử biệt hiệu là finch chẳng hạn) –

+0

Ture, trước tiên hãy thử chuyển đổi chuỗi của bạn (Finch) vào một chuỗi Hex sử dụng: var hexString = nickname.toHexString(); - sau đó vượt qua điều đó làm đối số để tạo objectID của bạn – user313551

Các vấn đề liên quan