Каков наилучший подход к созданию системы голосования для элемента, находящегося в очереди, срок действия которого истекает? Требуется фоновая задача? - PullRequest
0 голосов
/ 21 марта 2011

Я создаю приложение в Rails 3 (и Ruby 1.9.2), которое принимает заявки от нескольких пользователей. Приложение закрывает окно представлений через X времени. Затем все должны проголосовать (большими пальцами вверх / большими пальцами вниз) за представленные материалы. По истечении времени Y выигрывает тот, кто набрал наибольшее количество голосов, и процесс повторяется.

Я новичок, но у меня есть базовые модели, построенные на основе представлений, маршрутов RESTful, аутентификации пользователей с помощью Devise и т. Д. Но теперь мой опыт исчерпан, и я не совсем уверен, что лучший подход к построение «удерживающей» системы, которая будет отсчитывать время до тех пор, пока не будет принято ни одного голоса и не будет выбран победитель Я думаю, что я создам объект голосования, так что каждое представление может иметь много голосов. Но кажется, что, может быть, что-то нужно в фоновом режиме, чтобы проснуться после того, как таймер выключился для голосования и сказал: «Хорошо, этот период голосования закончился, теперь переместите победителя в БД и начните принимать новые предложения перед следующим туром голосования ». Это правильно или может быть проще?

Любые предложения о том, как я должен думать об этой концепции?

Спасибо !!

Ответы [ 2 ]

1 голос
/ 21 марта 2011

Итак, у вас есть какая-то модель Ballot. Ballot имеет много Submission с, отправка имеет много Vote с. Также есть модель WinningSubmission. Ballot has_one WinningSubmission.

Я думаю, что, вероятно, проще всего Ballot содержать временные метки для X и Y.

Если вы не хотите, чтобы какое-то задание cron опрашивало заполненные бюллетени для голосования, вы можете запустить общий before_filter в ApplicationController (или, предпочтительно, создать пустой контроллер только для этого фильтра, и другие контролеры, управляющие голосованием, наследуют его), который проверяет каждый запрос на наличие закрытых бюллетеней, но также не имеет победителей; затем подсчитайте победителей, прежде чем продолжить с запросом. Это похоже на работу работника, за исключением того, что он находится внутри веб-сервера, поэтому добавляет небольшую задержку ответа.

Что касается архитектуры Controller / View того, как представления и голоса являются create d, я бы, вероятно, имел три вложенных контроллера:

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, кроме действий 'create', но я предполагаю, что вы либо воспользуетесь дизайном стиля индекса на одной странице в уровень представления бюллетеней или серия представлений, по одному для каждого состояния, в котором может находиться бюллетень. Для простоты они, вероятно, будут разбросаны по действиям #index различных контроллеров.

Как и выше, если вы не хотите использовать cronjob или наемного работника, у меня будет BallotsController, SubmissionsController и VotesController all < 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
0 голосов
/ 21 марта 2011

Я не думаю, что вам нужны фоновые задачи - вместо этого просто установите AJAX-опросчик, который обновит страницу и отобразит форму голосования, когда она будет готова.

Таким образом, ваша заявка принимает голоса только в течение действительного времени (в частности, голоса подтверждают, что Time.now находится между временем начала и окончания представления). Это сохранит ваши данные в целости.

Затем в вашем HTML, просто начните с того, что обновляйте страницу каждую минуту, а затем заставляйте ее обновляться только тогда, когда начинается действительное время (и обновляйте снова, когда оно заканчивается).

...