我正在尝试实现一个类似于 stackoverflow 或 reddit 的投票系统,其中用户只能在给定的帖子上投票一次。
遵循此处给出的建议后
在 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 }]
});
根据当前用户,每个帖子都会有不同的视图,如果用户在upvote按钮或downvote按钮变为橙色(类似于stackoverflow)之前对帖子投票,那么我有以下(简化的)主干帖子模型:
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);
}
});
},
});
因此,如果用户之前没有在帖子上投票,则 votetype 以“0”开头,而它的“1”或“-1”取决于投票。在 upvote 函数中,当我更新并保存该帖子的投票类型时,我还发送了一个 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();
};
我可能有一些糟糕的设计决定,但到目前为止,这似乎工作正常。请告诉我是否可以对我的代码或我的设计进行任何改进。
现在是棘手的部分。在执行 collection.fetch() 之前,我必须以某种方式查看这两种模式并更改每个帖子的“投票类型”。我想出了一个像这样的丑陋解决方案:
https://gist.github.com/gorkemyurt/6042558
(我把它放在一个 gits 中,所以它可能更具可读性,对于丑陋的代码感到抱歉..)
一旦我根据用户更新每个帖子的投票类型,我会将其传递给我的主干视图,并在我的模板中执行一些非常基本的操作,例如:
<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>
该解决方案有效,但我认为每次用户打开页面以呈现帖子的自定义视图时查找所有帖子和用户投票的所有帖子并不是很有效.. 谁能想到更好的怎么做?我愿意接受有关我的代码的任何建议或批评。在此先感谢