0

私は現在、Rails アプリを開発しており、state_machine ジェムを使用して複雑なプロセスを顧客に案内しています。

プロセスの複数の状態で、一定期間後にイベントをトリガーする必要があります。たとえば、顧客が 5 日経っても注文を受け取ったことを確認していない場合、自動的に電子メールを送信して小包追跡プロセスを開始したいと考えています。

class Order < ActiveRecord::Base



    state_machine :initial => :confirmed do

        after_transition :on => :not_received_by_5_days, do |order, transition|
            order.send_email
            order. .....
            order. .....

        event :customer_confirmation do
            transition :confirmed => :order_received
        end

        event :not_received_by_5_days do
            transition :confirmed => :parcel_tracking_process
        end

        def send_email
            blabla
        end
    end

end

以前のソリューションをテストした後の編集:

一定期間後に遷移をトリガーするにはどうすればよいですか?

ありがとうございました、

クレマン

4

2 に答える 2

0

ソリューションを 2 つの主要なグループに分けるには、次のことができます。

  1. DelayedJobResque、またはSidekiqなどの Ruby/Rails キューイング ソリューションを使用します。また、
  2. cronjob を使用します。

これらのツールのいずれかをすでに使用している場合、またはそれらのいずれかを使用することになることがわかっている場合は、前者が最も理にかなっています。それらはすべて、始めるのにかなりの労力を必要とします。Resque と Sidekiq では Redis サーバーを構成する必要がありますが、DelayedJob では既存のデータベースを使用します。Resque ではさらに、ジョブをスケジュールするためのプラグインが必要ですが、DelayedJob と Sidekiq はジョブのスケジュールをネイティブにサポートしています。3 つすべてで、ジョブ モデルを作成し、ワーカーを実行するように構成する必要があります。

後者は、cron アクセス権があると仮定すると非常に単純です。Ruby でスクリプトを作成し、cron を介して自動的に実行されるようにスケジュールします。

私はしばらくの間 state_machine を使用していませんが、これは機能するはずです (そうでない場合は、アイデアが伝わります)。

#!/usr/bin/env /path/to/project/bin/rails runner
Order.where(state: 'confirmed').where("created_at <= #{5.days.ago}").find_each do |o|
  o.not_received_by_5_days
end

何が起きてる?Order オブジェクトが作成されるとすぐに、confirmed状態に入ります。そのため、ちょっとした調整が必要な注文を見つけるために、ActiveRecord クエリを実行して、confirmed5 日以上経過した状態の注文を見つけることができます。次に、各レコードを繰り返し処理し、not_received_by_5_days イベントを発生させます。

すべては、Rails ランナーによって管理されます。Rails ランナーは、Rails 環境をロードし、そこでスクリプトのコードを実行します (Rails コンソールを使用するのと同じですが、人間の介入は必要ありません)。

cron で 1 日に 1 回か 2 回 (メールをもっと頻繁に送信したい場合はもっと頻繁に) 実行すると、スクリプトは少なくとも 5 日経過したすべての不在注文を見つけてワークフローに移動します。not_received_by_5_days イベントが発生すると、コードはユーザーを新しい状態に移動する (はずである) ため、その後のスクリプトの実行では表示されなくなり、リマインダーは 1 回だけ受信されます。

于 2013-07-30T20:23:25.293 に答える