Rails NoMethodError (неопределенный метод `humanize 'для nil: NilClass) в почте: - PullRequest
0 голосов
/ 21 июня 2019

У меня есть такая работа в моем приложении на 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 (я столкнулся с этой проблемой на сервере dev, затем воспроизвел это поведение в консоли) для запуска 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 в строке 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 в Services::NewAnswerNotify.

1 Ответ

1 голос
/ 24 июня 2019

Несколько предложений:

  • Вы должны напрямую использовать методы класса ActionMailer вместо создания нового почтовика с new.Вероятно, это источник ошибки
  • Поскольку ваш NewAnswerNotify вложен в Services, использование корневого пространства имен ::NewAnswerNotifyMailer также сделает его менее двусмысленным (некоторые люди могут не согласиться со мной в этомодин, но в прошлом у меня было так много ошибок корневого пространства имен, что я склонен систематически использовать префикс :: сейчас
  • Остерегайтесь загрузки классов, которая работает по-разному для class Services::NewAnswerNotify и module 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 или кто-то еще, кому может потребоваться уведомление (это полностью зависит от вашей бизнес-модели, конечно, не стесняйтесь игнорировать этоЗаметим)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...