2016-04-04 7 views
1

これは私の最初の投稿ですので、初心者の間違いを事前に謝罪します。私はこの問題のさまざまな解決策を研究しようとしましたが、これまで私の特別なケースに合っていると思われるものは見つかっていません。特定の日付の後3日ごとに通知メールを送信

私は個人がevaluationsを作成するには、アプリを持っている、と最小要件が7日created_at日後に満たされていない場合、私は行動を取るためにそれらを促す3日ごとに通知メールを送信したいです。

reminders.rbファイルが3から7.daysReminders::LIMBO_EMAIL_INTERVAL_DAYSセットにEvaluation::ASSESSMENTS_COMPLETION_WAIT_TIMEセットで、次のようになります。

def self.send_peer_shortage_notifications 
    time = Time.current - Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME 
    range = time..Time.current 
    today = Time.current.to_date 

    evaluations = Evaluation.arel_table 
    assessments = Assessment.arel_table 

    left_join = evaluations 
       .join(assessments, Arel::Nodes::OuterJoin) 
       .on(evaluations[:id].eq(assessments[:evaluation_id]), 
        assessments[:state].in([:pending, :complete]), 
        assessments[:assessor_id].not_in([evaluations[:user_id], 
                 evaluations[:manager_id]])) 
       .join_sources 

    relation = Evaluation 
       .in_process 
       .joins(left_join) 
       .where(created_at: range) 
       .group(:user_id) 
       .having(evaluations[:user_id].count.lt(Evaluation::MINIMUM_NUM_PEERS)) 

    relation.find_each do |evaluation| 
     days_in_limbo = (today - (evaluation.created_at + Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME).to_date).to_i 
     if days_in_limbo % Reminders::LIMBO_EMAIL_INTERVAL_DAYS == 0 
     EvaluationMailer.delay.limbo_notification(evaluation) 
     end 
    end 
    end 

reminders_rspec.rbは、この(最初のテストが失敗したと私はその理由を把握することはできません)のように見えます

context 'minimum number of peer assessments not in pending/complete and limbo email interval day' do 
     limbo_interval_array = Array.new(10) { |i| i*Reminders::LIMBO_EMAIL_INTERVAL_DAYS } 

     let!(:evaluation) { create(:evaluation, created_at: (Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME + limbo_interval_array.sample.days).ago) } 
     let!(:assessments) do 
     create_list(:assessment, 
     Evaluation::MINIMUM_NUM_PEERS, 
     evaluation: evaluation, 
     state: [:expired, :declined].sample) 
     end 

     it 'sends limbo email' do 
     expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1) 
     end 
    end 

    context 'on every non-third day since limbo' do 
     array = (1..20).to_a 
     limbo_interval_array = Array.new(10) { |i| i*Reminders::LIMBO_EMAIL_INTERVAL_DAYS } 
     non_limbo_interval_array = array - limbo_interval_array 


     let!(:evaluation) { create(:evaluation, created_at: (Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME + non_limbo_interval_array.sample.days).ago) } 
     let!(:assessments) do 
     create_list(:assessment, 
     Evaluation::MINIMUM_NUM_PEERS, 
     evaluation: evaluation, 
     state: [:expired, :declined].sample) 
     end 

     it 'sends nothing' do 
     expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(0) 
     end 
    end 

これを書く簡単な方法はありますか?これは私がやろうとしていることに対しては過度に複雑に思えますが、よりシンプルな方法を見つけることができませんでした。

+0

私は多くのsh *** y最初の記事を見る。これはかなり大丈夫です。 +1あなたのため – m02ph3u5

答えて

0

確かに、これはもっと複雑になっているようです。非同期的にあなたの電子メール通知をディスパッチするキューイングバックエンドを使用するリマインダが評価を作成した後、7日に送信されることになるので、遅延メールがEvaluationsController#createアクションをキューに入れることになります。

class EvaluationsController < ApplicationController 

def create 
    # Do whatever it is you do to create an evaluation 

    if @evaluation.valid? 
    EvaluationMailer.delay_for(7.days).limbo_notification(evaluation.id) # Pass an ID rather than a model object, and use `find_by` within `limbo_notification` 
    # redirect or whatever... 
    end 
end 

、すべてのハードキューイングバックエンドActiveJobによって作業が行われ、7日後に電子メールが自動的に送信されます。

キューイングのバックエンドは大きなテーマです。どのように動作するかについて詳しく説明するのではなく、http://edgeguides.rubyonrails.org/active_job_basics.htmlのドキュメントを参照してください。特定のキューイングバックエンドについては、RedisでSidekiqをお勧めします。

+0

ありがとう、良い情報! – jnapolitan

関連する問題