【问题标题】:Rails ApplicationMailer method not called when invoked调用时未调用 Rails ApplicationMailer 方法
【发布时间】:2015-04-11 01:38:38
【问题描述】:

我正在尝试使用他们的ApplicationMailer 机制从 Ruby on Rails v4.2 发送电子邮件。不幸的是,至少在开发环境控制台中,我们创建的ApplicationMailer 的子类并没有调用我们试图调用的方法:

class RecurringScheduleNotifier < ApplicationMailer
  default from: 'notifications@example.com'
  def send_schedule_reminder(student)
    logger.debug('This never gets called :(')
    send_schedule_reminder_email(student, student.email).deliver
  end
  def send_schedule_reminder_email(user, email)
    mail(to: email, subject: 'Test subject')
  end
end

class Student < ActiveRecord::Base
  def self.send_emails
    Student.all.each do |student|
      logger.debug('This does get called')
      RecurringScheduleNotifier.send_schedule_reminder(student)
      logger.debug('This also get called')
    end
  end
end

如果我直接在控制台中运行邮件程序,它会很好地发送电子邮件:

RecurringScheduleNotifier.send_schedule_reminder(Student.first)

所有 3 条记录器消息均按预期输出并发送电子邮件。但是,如果我从控制台调用 Student 类方法,这不起作用:

Student.send_emails

我没有收到错误消息,但只输出 Student 类中的 2 条记录器消息。 RecurringScheduleNotifier中的logger消息根本不输出!

我错过了什么?这很奇怪,因为 Student.send_emails 真正所做的只是为每个学生调用 RecurringScheduleNotifier.send_schedule_reminder(我的开发环境中现在只有 1 个)。直接对那个学生调用RecurringScheduleNotifier.send_schedule_reminder 效果很好。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 actionmailer ruby-on-rails-4.2


    【解决方案1】:

    当您调用邮件程序方法时,该方法返回一个ActionMailer::MessageDelivery。您必须致电deliver_nowdeliver_later 发送电子邮件。

    所以在你的情况下,在你的用户模型中,调用......

    RecurringScheduleNotifier.send_schedule_reminder(student).deliver_later
    

    ...应该可以解决问题。

    我不确定您的邮件中是否有两种方法。您可能希望将它们合并为一个。喜欢:

    def send_schedule_reminder(student)
      @student = student
      logger.debug('This never gets called :(')
      mail(to: student.email, subject: 'Test subject')
    end
    

    【讨论】:

    • deliver 函数显然不是这里的问题......因为第一个 logger 调用永远不会被调用。
    • @Sander 似乎是正确的。我刚遇到同样的问题。如果没有尾随 .deliver_now.deliver_later 调用,则不会调用用户定义的操作邮件子类的方法。请注意,当您定义邮件程序的方法时,您定义了 instance 方法,但是在您的代码中您调用的是 class 方法,所以这里涉及到一些 Rails 魔法,一种惰性求值.
    【解决方案2】:

    为了补充Johann 的评论,ActionMailer::Base 类有这种特殊的方式来调用他们所有的实例方法作为类方法here is the source code。我不知道这是为什么,只要我看到只有这个类实现了这个“模式”(¿?)。

    【讨论】:

      猜你喜欢
      • 2021-08-22
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      • 2013-09-03
      • 2013-04-28
      相关资源
      最近更新 更多