将Rails NoMethodError(对于nil:NilClass的未定义方法'humanize')发送给以下地址:

时间:2019-06-21 10:08:31

标签: ruby-on-rails ruby ruby-on-rails-5

我在Rails应用程序中有这样的工作:

class NewAnswerNotifyJob < ApplicationJob
  queue_as :default

  def perform(answer)
    Services::NewAnswerNotify.new.send_notify(answer)
  end
end

Services::NewAnswerNotify

class Services::NewAnswerNotify
  def send_notify(answer)
    NewAnswerNotifyMailer.new.notify(answer)
  end
end

NewAnswerNotifyMailer

class NewAnswerNotifyMailer < ApplicationMailer

  def notify(answer)
    @answer   = answer
    @question = answer.question
    @author   = answer.question.author

    mail to: @author.email
  end
end

当我在Rails控制台中尝试时(我在开发服务器上遇到了此问题,然后在控制台中重播了此行为)以Services::NewAnswerNotify#send_notify运行answer时出现了这样的错误:

2.6.0 :023 > answer = Answer.first
  Answer Load (0.5ms)  SELECT  "answers".* FROM "answers" ORDER BY "answers"."best_solution" DESC LIMIT $1  [["LIMIT", 1]]
 => #<Answer id: 76, body: "answer body", question_id: 2, created_at: "2019-05-01 18:43:16", updated_at: "2019-05-28 15:38:16", author_id: 1, best_solution: true> 
2.6.0 :024 > Services::NewAnswerNotify.new.send_notify(answer)
  Question Load (0.6ms)  SELECT  "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
Traceback (most recent call last):
        3: from (irb):24
        2: from app/services/new_answer_notify.rb:3:in `send_notify'
        1: from app/mailers/new_answer_notify_mailer.rb:8:in `notify'
NoMethodError (undefined method `humanize' for nil:NilClass)
2.6.0 :025 > 

因此,错误发生在mail to: @author.email的{​​{1}}行中,但是当邮件本身按计划工作时:

NewAnswerNotifyMailer

我不知道问题出在哪里,为什么我在2.6.0 :025 > answer = Answer.first Answer Load (0.7ms) SELECT "answers".* FROM "answers" ORDER BY "answers"."best_solution" DESC LIMIT $1 [["LIMIT", 1]] => #<Answer id: 76, body: "for flexbox grid columns also means you can set th...", question_id: 2, created_at: "2019-05-01 18:43:16", updated_at: "2019-05-28 15:38:16", author_id: 1, best_solution: true> 2.6.0 :026 > NewAnswerNotifyMailer.notify(answer) Question Load (0.5ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]] User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] [i18n-debug] en.new_answer_notify_mailer.notify.subject => nil Rendering new_answer_notify_mailer/notify.html.slim within layouts/mailer Rendered new_answer_notify_mailer/notify.html.slim within layouts/mailer (4.7ms) Rendering new_answer_notify_mailer/notify.text.slim within layouts/mailer Rendered new_answer_notify_mailer/notify.text.slim within layouts/mailer (3.5ms) NewAnswerNotifyMailer#notify: processed outbound mail in 100.5ms => #<Mail::Message:70164808395160, Multipart: true, Headers: <From: from@example.com>, <To: codcore@gmail.com>, <Subject: Notify>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_5d0cac2d80291_b85a3fd081039fd052340"; charset=UTF-8>> 遇到Nil

1 个答案:

答案 0 :(得分:1)

一些建议:

  • 您应该直接使用ActionMailer类方法,而不要使用new实例化新的邮件程序。这可能是错误的来源
  • 由于您的NewAnswerNotify嵌套在Services下,因此使用根命名空间::NewAnswerNotifyMailer也会减少歧义(有些人可能对此表示反对,但是我过去有很多根名称空间错误,以至于我现在倾向于系统地使用::前缀)
  • 当心类加载对于class Services::NewAnswerNotifymodule Services class NewAnswerNotification的工作方式有所不同(有关此主题的许多现有问题)
module Services
  class NewAnswerNotify
    def send_notify(answer)
      ::NewAnswerNotifyMailer.notify(answer).deliver_now # instead of .new.notify
    end
  end
end

关于变量和英文的一些其他注释

我宁愿使用

  • Services::NewAnswerNotification
  • NewAnswerNotificationMailer
  • def send_notification(answer)def notify(answer)

从长远来看,在维护代码库之后,也许是经验中的最后一条建议:更明确地告知您要通知谁def notify_question_author_of_new_answer,因为稍后您可能会拥有notify_question_subscribers_of_new_answer或可能需要通知其他人(这完全取决于您的业务模型,请随时忽略此评论)