2017-02-13 4 views
1

У меня есть приложение rails, в котором заказ назначается поставщику для принятия или отклонения заказа, который хранится как статус в таблице назначения заказа этим поставщиком для этого конкретного заказа. Если заказ не будет принят или отклонен поставщиком в течение 15 минут, тогда заказ должен быть автоматически отклонен, то есть статус обновлен, чтобы автоматически отклонить этот поставщик и сохранить его в таблице. Как мне достичь этой задачи?Как установить таймер для автоматического задания значения поля, если он не обновлен в течение 15 минут в рельсах с момента создания?

Estamps::Order 

has_many :order_assignments 
belongs_to :vendor 

Estamps::Vendor 

has_many :order_assignments 
has_many :orders 

Estamps::OrderAssignment 

belongs_to :vendor, class_name: 'Estamps::Vendor' 
belongs_to :order, class_name: 'Estamps::Order' 

Схема для OrderAssignment таблицы:

t.string "status" 
    t.integer "vendor_id" 
    t.integer "order_id 

После назначения заказ поставщику, поставщик должен обновить статус принят, отвергнут. Если не обновлено для любого назначенного заказа в течение 15 минут, статус должен быть автоматически отклонен. Это должно произойти для любого назначенного порядка. Может ли кто-нибудь помочь мне в этом? Я новичок с рельсами.

ответ

0

Это может быть достигнуто с помощью планировщика, такого как sidekiq или resque. Это будет делать эти действия в фоновом режиме и не будет беспокоить контроллер. Но проблема в том, что нам нужен сервер redis для выполнения этой работы. В любом случае проверьте documentation.

1

Ответы здесь правильно, что это хорошо подходит для очереди, но учтите, что Rails выставил хороший API поверх всех очередей, называемых activejob: http://edgeguides.rubyonrails.org/active_job_basics.html

Все, что вам нужно сделать, это выбрать работу очередь (популярные варианты: sidekiq, resque, delayed_job). Обратите внимание, что delayed_job будет проще всего развертывать, поскольку он не имеет дополнительных зависимостей, таких как redis (https://github.com/collectiveidea/delayed_job).

После установки, например delayed_job все, что осталось сделать, это поставить в очередь работу после создания присвоения заказа, который проверяет его статус через 15 минут, например, так:

Estamps::OrderAssignment 
after_create :enqueue_check_status 

def enqueue_check_status 
    #this is activejob syntax to enqueue a job at a later time 
    OrderStatusJob.set(wait: 15.minutes).perform_later(self.id) 
end 

#the rails way to define a job class 
class OrderStatusJobJob < ApplicationJob 
    queue_as :default 

    def perform(order_assignment_id) 
     order_assignment = OrderAssignment.find(order_assignment_id) 
     if order_assignment.status != true 
     order_assignment.update_attribute('status', 'REJECTED') 
     end 
    end 
end 
+0

Обратите внимание, что вы могли бы определить after_create обратного вызова на модели заказа аналогичным образом, это может даже иметь больше смысла для ваших нужд. –

+0

Дело в том, что мне не нужно уничтожать заказ, просто обновите статус заказа в статусе назначения заказа как «ОТКАЗЫВ». Во-вторых, метод wait в модели заставит все приложение ждать или продолжит создавать заказы и назначать и устанавливать их статус или выполнять любую другую задачу без перерыва, но выполнит указанную операцию для этой конкретной записи order_assignment после 15 минут? Извините, если вопрос кажется глупым, просто хочу понять ноу-хау. –

+0

Это не приведет к тому, что все приложение будет ждать, это точно точка очередей и фоновых работников, все происходит на заднем плане, что означает, что обычно выполняется другой процесс, который обрабатывает все задания, поэтому он не влияет на ваши основные рельсы app (кроме совместного использования того же db, но обычно это нормально). Должна быть нулевая проблема с изменением кода, который я написал, чтобы изменить статус на REJECTED (просто вызывается update_attribute вместо уничтожения), сообщите мне, есть ли у вас проблема. –