为队列中将过期的项目构建投票系统的最佳方法是什么?需要后台任务吗?

发布于 2024-10-25 02:55:51 字数 400 浏览 6 评论 0 原文

我正在 Rails 3(和 Ruby 1.9.2)中构建一个应用程序,它接受多个用户的提交。应用程序会在 X 时间后关闭提交窗口。然后,每个人都要对提交的内容进行投票(赞成/反对)。 Y 时间后,得票最多的人“获胜”,并且重复该过程。

我是一个菜鸟,但我已经构建了包含提交、RESTful 路由、使用 Devise 进行用户身份验证等的基本模型。但现在我的经验已经耗尽,我不太确定构建“的最佳方法是什么”保留”系统将倒计时,直到不接受任何选票并选出获胜者。我想我会创建一个投票对象,这样每次提交都可以有很多票。但似乎在投票计时器耗尽后,后台可能需要一些东西来唤醒并说:“好吧,这个投票期已经结束,现在将获胜者移入数据库并在下一轮投票之前开始接受新的提交”。这是正确的还是可以比这更简单?

关于我应该如何思考这个概念有什么建议吗?

谢谢!!

I am building an app in Rails 3 (and Ruby 1.9.2) which takes submissions from multiple users. The app closes the submissions window after X amount of time. Then, everyone is to vote (thumbs up/thumbs down) on the submissions. After Y amount of time, the one with the most votes "wins", and the process repeats.

I'm a noob, but I have the basic models built housing the submissions, RESTful routes, user authentication with Devise, etc. But now my experience has run out and I'm not quite sure what the best approach is to building the "holding" system that will countdown the time until no votes are accepted and a winner is chosen. I think I will create a vote object, so that each submission can have many votes. But it seems like maybe something is needed in the background to wake up after the timer runs down for voting and say, "okay, this voting period has ended, now move the winner into the DB and start taking new submissions before the next voting round". Is this right or can it be simpler than this?

Any suggestions on how I should think about this concept?

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

春庭雪 2024-11-01 02:55:51

所以你已经有了某种Ballot 模型。 Ballot有很多Submission,提交有很多Vote。还有一个 WinningSubmission 模型。 选票 has_one WinningSubmission

我认为让 Ballot 包含 X 和 Y 的时间戳可能是最简单的。

如果您不想让某些 cron 作业轮询已完成投票的选票,您可以运行通用 ApplicationController 中的 >before_filter (或者,最好只为此过滤器创建一个空白控制器,并让管理投票的其他控制器继承它),检查每个请求以查看是否所有投票均已结束,但也没有获胜者;然后在继续请求之前计算获胜者。它就像一个工作人员,只不过它位于网络服务器内,因此它会增加一些少量的响应延迟。

至于提交和投票如何创建的控制器/视图架构,我可能会有三次嵌套控制器:

resources :ballots do       # These blocks may need to pass in their object 
                            # depending on your rails version.

  resources :submissions do 
    # POST to ballot_submissions_path(@ballot) creates subs's.

    resources :votes # POST to ballot_submission_votes_path(@b, @s) creates votes.
  end 
end 

我必须更多地了解您的交互设计,以帮助处理任何视图/ ajax 级别的交互超出了“创建”操作的范围,但我猜您要么在选票提交级别采用单页索引样式设计,要么使用一系列视图,每个州可以使用一个选票为了简单起见,这些可能会分散在各个控制器的 #index 操作中。

如上所述,如果您不想使用 cronjob 或作业工作者,我将 BallotsControllerSubmissionsControllerVotesController 全部 <代码>< BallotCompleterController 像这样:

class VotesController < BallotCompleterController
#your vote handling actions would go here.
end

class BallotCompleterController < ApplicationController
  before_filter :complete_unfinished_ballots
  protected
  def complete_unfinished_ballots
     Ballot.expectant.calculate_all!
  end
  #and that's all that's in here
end

class Ballot < ActiveRecord::Base
  #...has_many etc's
  named_scope :expectant, lambda{ 
   {:select => "ballots.*",
    :conditions => ['votes_until < ? and winning_submissions.id is null', Time.current],
    :joins => 'left outer join winning_submissions 
               on winning_submissions.ballot_id = ballots.id', 
    :readonly => false} }

 def self.calculate_all!
   self.each(&:'calculate_winning_submission!') 
 end

 def calculate_winning_submission!
   #calc and save the winning_submission for this ballot
 end

end

So you've got some kind of Ballot model. Ballot has many Submissions, submission has many Votes. There's a WinningSubmission model as well. Ballot has_one WinningSubmission.

I think it's probably easiest to have Ballot contain the timestamps for X and Y.

If you don't want to have some cron job that polls for completed-voted-ballots, you can run a general before_filter in ApplicationController (or, preferably, create a blank controller just for this filter, and have the other controllers that manage the voting inherit from it) that checks on each request to see if any ballots are closed, but also have no winners; then calculate the winners on those, before continuing with the request. It's just like a job worker, except it's within the webserver, so it adds some small amount of response delay.

As far as the Controller/View architecture of how submissions and votes are created, I'd probably have thrice nested controllers:

resources :ballots do       # These blocks may need to pass in their object 
                            # depending on your rails version.

  resources :submissions do 
    # POST to ballot_submissions_path(@ballot) creates subs's.

    resources :votes # POST to ballot_submission_votes_path(@b, @s) creates votes.
  end 
end 

I'd have to know more about your interaction design to help with any view/ajax level interaction beyond the 'create' actions, but I'm guessing you'd either go with a one-page index style design at the ballot-submission level, or with a series of views, one for each state a ballot can be in. These would probably get sprinkled across the #index actions of the various controllers for simplicity's sake.

As above, if you didn't want to use a cronjob or job worker, I'd have BallotsController, SubmissionsController, and VotesController all < BallotCompleterController like so:

class VotesController < BallotCompleterController
#your vote handling actions would go here.
end

class BallotCompleterController < ApplicationController
  before_filter :complete_unfinished_ballots
  protected
  def complete_unfinished_ballots
     Ballot.expectant.calculate_all!
  end
  #and that's all that's in here
end

class Ballot < ActiveRecord::Base
  #...has_many etc's
  named_scope :expectant, lambda{ 
   {:select => "ballots.*",
    :conditions => ['votes_until < ? and winning_submissions.id is null', Time.current],
    :joins => 'left outer join winning_submissions 
               on winning_submissions.ballot_id = ballots.id', 
    :readonly => false} }

 def self.calculate_all!
   self.each(&:'calculate_winning_submission!') 
 end

 def calculate_winning_submission!
   #calc and save the winning_submission for this ballot
 end

end
三寸金莲 2024-11-01 02:55:51

我认为您不需要后台任务 - 相反,只需使用 AJAX 轮询器来刷新页面并在准备就绪时显示投票表单。

因此,您的提交仅在有效时间内接受投票(具体来说,投票验证 Time.now 位于提交开始/结束时间之间)。这将使您的数据保持完整。

然后在 HTML 上,首先让页面每分钟刷新一次,然后让它仅在有效时间开始时刷新(并在有效时间结束时再次刷新)。

I don't think you need background tasks -- instead, just have an AJAX poller that refreshes the page and display the voting form when it's ready.

So your submission only accepts votes during the valid time (specifically the votes validates that Time.now is between the submission start/end time). That'll keep your data intact.

Then on your HTML, just start by having your page refresh every minute, and then get it to only refresh when the valid time starts (and refresh again when it ends).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文