के साथ उपरोक्त और डाउनवोट मैं स्टैक ओवरफ्लो या रेडडिट के समान मतदान प्रणाली को कार्यान्वित करने की कोशिश कर रहा हूं जहां उपयोगकर्ता को किसी दिए गए पोस्ट पर केवल एक बार मतदान करने की अनुमति होगी।बैकबोन, एक्सप्रेस और मोंगोस
यहाँ दी
storing upvotes/downvotes in mongodb
मैं upvotes और downvotes स्टोर करने के लिए दो स्कीमा बनाया है सलाह पालन करने के बाद। प्रत्येक उपयोगकर्ता के लिए मैं उन पदों का ट्रैक रख रहा हूं जिन पर उपयोगकर्ता ने मतदान किया है।
पोस्ट स्कीमा:
var postSchema = new Schema({
name: String,
votes: Number,
votetype: Number,
postedBy: { type: String, ref: 'User' },
});
उपयोगकर्ता स्कीमा:
var userSchema = new Schema({
twittername: String,
twitterID: Number,
votedPosts : [{ _id : mongoose.Schema.Types.ObjectId , votetype: Number }]
});
वर्तमान उपयोगकर्ता के आधार पर प्रत्येक पोस्ट, एक अलग दृष्टिकोण है करने के लिए जा रहा है, तो उपयोगकर्ता से पहले पद पर मतदान किया है अपवॉट बटन या डाउनवोट बटन नारंगी (स्टैक ओवरफ्लो के समान) होने जा रहा है, इसलिए मेरे पास पोस्ट के लिए निम्नलिखित (सरलीकृत) रीढ़ की हड्डी मॉडल है:
var PostModel = Backbone.Model.extend({
urlRoot : '/tweet',
idAttribute: '_id',
defaults:{
name: '',
votes: 0,
votetype: 0,
postedBy : '',
},
upvote: function(){
this.set ({votetype : 1 }, {votes : this.get('votes') + 1});
this.save();
$.ajax({
type: "POST",
url:"/upvote",
data : {postID : this.id , userID : window.userID , vote: 1},
success : function(result){
console.log(result);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
},
});
तो वोटटाइप "0" से शुरू होता है यदि उपयोगकर्ता ने पहले पोस्ट पर मतदान नहीं किया है, और वोट के आधार पर इसका "1" या "-1" है। वोट दें समारोह में, के रूप में मैं अद्यतन और उस पोस्ट की votetype बचाने के लिए, मैं भी एक ajax अनुरोध के बाद की तरह पद नियंत्रक में उपयोगकर्ता के वोट पदों सरणी के लिए उस पोस्ट को जोड़ने के लिए भेजें:
exports.upvote = function(req,res){
var postID = req.body.postID;
var newvotetype = req.body.vote;
User.findOne({twitterID : req.body.userID}, {votedPosts : { $elemMatch: { "_id": postID }}},
function(err, post) {
if (post.votedPosts.length == 0) {
//append to the array
User.update({twitterID : req.body.userID} , { $push : {votedPosts : {_id : postID , votetype: newvotetype}}} ,function (err, user, raw) {
if (err){console.log(err);}
});
console.log(post);
console.log("no one has voted on this before");
}
else {
//update in the existing array
User.update({twitterID : req.body.userID, 'votedPosts._id': postID }, { $set : {'votedPosts.$.votetype' : newvotetype}} ,function (err, user, raw) {
if (err){console.log(err);}
});
}
}
);
res.send("success");
res.end();
};
मैं हो सकता है कुछ खराब डिजाइन फैसले लेकिन अब तक ऐसा लगता है कि यह ठीक काम करता है। कृपया मुझे बताएं कि क्या मैं अपने कोड पर कुछ सुधार कर सकता हूं, या मेरे डिजाइन पर कुछ और कर सकता हूं।
अब मुश्किल हिस्सा आता है।
https://gist.github.com/gorkemyurt/6042558
(मैं: किसी तरह मैं इन स्कीमा के दोनों के माध्यम से देखने के लिए और एक collection.fetch() करने से पहले प्रत्येक पोस्ट की "votetype" बदलना होगा .. मैं इस तरह एक बदसूरत समाधान के साथ आया था इसे एक गिट्स में डाल दें ताकि शायद बदसूरत कोड के लिए खेद हो। ..
और एक बार जब मैं उपयोगकर्ता के आधार पर प्रत्येक पोस्ट के वोट प्रकार को अपडेट करता हूं तो मैं इसे अपने रीढ़ की हड्डी के दृश्य में भेजता हूं, और मेरे टेम्पलेट में कुछ बहुत बुनियादी करें:
<div class="post-container">
<div id="arrow-container">
<% if (votetype == 1) { %>
<p><img id="arrowup" src="/images/arrow-up-orange.jpg"></p>
<p><img id="arrowdown" src="/images/arrow-down.jpg"></p>
<% } %>
<% if (votetype == 0) { %>
<p><img id="arrowup" src="/images/arrow-up.jpg"></p>
<p><img id="arrowdown" src="/images/arrow-down.jpg"></p>
<% } %>
<% if (votetype == -1) { %>
<p><img id="arrowup" src="/images/arrow-up.jpg"></p>
<p><img id="arrowdown" src="/images/arrow-down-orange.jpg"></p>
<% } %>
</div>
<div id="text-container">
<p><h2><%- name %></h2></p>
<p><%- dateCreated %></p>
<p>Posted by: <%- postedBy %></p>
</div>
</div>
यह समाधान काम करता है, लेकिन मुझे लगता है कि सभी पदों और सभी पोस्टों को देखने के लिए यह वास्तव में कुशल नहीं है कि उपयोगकर्ता ने हर बार मतदान किया है जब उपयोगकर्ता पोस्ट के कस्टम दृश्य को प्रस्तुत करने के लिए पृष्ठ खोलता है .. क्या कोई भी इस बारे में सोच सकता है ऐसा करने का बेहतर तरीका? मैं अपने कोड के बारे में कोई सलाह या आलोचना के लिए खुला रहा हूँ .. अग्रिम
आपके उत्तर के लिए बहुत बहुत धन्यवाद, यह वास्तव में सहायक था। मैं सिर्फ सीखने की कोशिश कर रहा हूं .. क्या आप इस भाग को फिर से स्पष्ट कर सकते हैं "लेकिन, अगर आपका हमलावर 100 से 1000 वोट भेजेगा तो आपका आवेदन कैसे प्रतिक्रिया देगा? यह ऑपरेशन परमाणु होना चाहिए, और जब आप बनाते हैं तो आपको सर्वर पर वोट बढ़ाना चाहिए पोस्ट अप/अपवोट एंडपॉइंट के लिए अनुरोध। " –
हां, आपने जो लिखा है, मैंने निष्कर्ष निकाला है कि आप दो अनुरोध करते हैं: एक जब आप 'पोस्टमोडेल' को सहेजते हैं: this.save(); और जब आप 'POST/upvote' बनाते हैं तो इसके ठीक बाद। आप इन अनुरोधों को उपयोगकर्ता वोट असाइन करने के लिए करते हैं, और कहीं और की तरह, आपको यह सुनिश्चित करना होगा कि उपयोगकर्ता इसका शोषण नहीं कर सकें। क्या होगा यदि कुछ उपयोगकर्ता केवल पहला अनुरोध भेजे जाएंगे - जो कोई दूसरा वोट भेजे बिना वोट बढ़ाता है - यह मूल रूप से अपने वोटों को अनाम बना देता है। उचित तरीका सिर्फ 'this.save' को कॉल किए बिना मॉडल में नए मानों को निर्दिष्ट करेगा, और */upvote' –
पर * आपके * सर्वर-साइड कोड से डेटाबेस में लिखना होगा, मैं वोट कैसे जोड़ूं या बदलूं? मोंगोडीबी की मेरी वर्तमान समझ से मुझे पहले देखना होगा कि क्या उपयोगकर्ता के लिए वोट है या वोट जोड़ने या बदलने से पहले। लेकिन क्या होता है अगर वोट देने के बाद उसके लिए एक और वोट जोड़ा जाता है? –