0

Q&Aサービスを運営しています。管理者ができることの1つは、質問をオフトピックとしてマークすることです。彼らがそうするとき、彼らの電子メールが話題から外れていることを彼らに告げる質問をした人に電子メールが送られます。

電子メール通知はdelayed_jobを介して送信されます。

QuestionMailer.delay.notify_asker_of_offtopic_flag question

ただし、場合によっては、誰かが誤って質問をオフトピックとしてマークしたり、気が変わったりすることがあります。最初に質問した人に誤った通知が届くのを防ぐために、短い遅延を作成し、メーラー要求が実行されたときに質問がまだトピックから外れているかどうかを評価します。

メーラーへの遅延呼び出し:

QuestionMailer.delay(run_at: Time.now + 3.minutes).notify_asker_of_offtopic_flag(question)

メーラー:

class QuestionMailer
  ...
  def notify_asker_of_offtopic_flag question
     if question.offtopic?
       # do mailing
     end
  end
end

残念ながら、これはそれほど単純ではありません。ifブロックによってエラーが発生し、delayed_jobがジョブを何度も再試行するためです。

QuestionMailer私は現在、同じ目的を達成するためにいくつかのかなり回り道の方法を試していますが、エラーをトリガーせずにアクションを中止する方法を本当に見つけたいと思います。これは可能ですか?

4

2 に答える 2

2

その後、メーラーを遅らせないでください。おそらく、Questionクラスの別のクラスメソッドを遅らせますか?質問のIDを渡し、その遅延メソッド内で、質問がまだトピックから外れているかどうかを確認し、そうである場合は同期して電子メールを送信します。

基本的に、notify_asker_of_offtopic_flagを質問モデルに移動すると、メール送信が同期されます(メソッドの名前を変更すると確信しています)。

コアのメールアクション自体の中でperform_deliveriesをfalseに設定することで配信を防ぐことについて話し合っていますが、私は100%どこで、どのようにそれが終わるのかではありません。

于 2012-07-26T19:24:39.103 に答える
1

@Adityaの答えは基本的に正しかったのですが、物事をすっきりと整理するために、Mailerオブジェクトのメソッドを維持したかったのです。これには、いくつかの追加のハックが必要でした。

遅延する可能性のある新しいClassメソッドをメーラーに作成します

インスタンスのメーラーメソッドをキャンセルしようとする場合の問題は、メソッドが中止されるのを防ぐレンダリングやその他の処理を本質的にトリガーすることです。ただし、それでもすべてのメーラーロジックをまとめておきたいと思います。

私がこれを行った方法は、インスタンスメソッドの代わりにクラスメソッドを使用することでした。これにより、インスタンスでメソッドを呼び出すときに起動するすべてのフックが回避されましたActionMailerが、それでもコードを整理してまとめることができました

class QuestionMailer
  ...
  def notify_asker_of_offtopic_flag question
    ...
  end

  def self.notify_asker_of_offtopic_flag question_if question
    if question.offtopic?
      QuestionMailer.notify_asker_of_offtopic_flag question
    end
  end
end

遅延ジョブを使用するためのNB修正

これは、に対処するために必要な1つのわずかなハックを除いて機能しdelayed_jobます。

メーラーを処理する場合、delayed_jobは.deliver、メールを配信するために、返されたオブジェクトを常に呼び出します。これは、メールオブジェクトを返す場合は問題ありませんが、この場合はnilを返します。したがって、呼び出しをdelayed_job試み 、すべてが失敗します。.delivernil

これを説明するために、dupe.deliverメソッドを含むダミーのメーラーオブジェクトを返すだけです。

class QuestionMailer
  ...
  class DummyMailer
    def deliver
      return true
    end
  end

  def notify_asker_of_offtopic_flag question
    # do mailing stuff
  end

  def self.notify_asker_of_offtopic_flag question_if question
    if question.offtopic?
      QuestionMailer.notify_asker_of_offtopic_flag question
    else
      DummyMailer.new
    end
  end
end
于 2012-07-27T11:20:12.167 に答える