Rails 4 Sidekiq nicht initialisierter konstanter Fehler
-
21-12-2019 - |
Frage
Ich habe ein Problem mit meiner Anwendung. Beim Versuch, E-Mails im Hintergrund zu senden, erhalte ich eine Fehlermeldung uninitialized constant AnswersController::LazyDoer
, ich habe nicht die geringste Ahnung, warum es nicht funktioniert, irgendwelche Vorschläge?
Mein Arbeiter ist da app/workers/lazy_doer.rb
Hier ist mein Controller:
class AnswersController < ApplicationController
before_action :authenticate_user!
before_action :set_question, except: [:adding_likes,:accept]
def create
@answer = Answer.new(answer_params)
@answer.user_id = current_user.id
@answer.question_id = @question.id
@question_owner = User.find(@question.user_id)
if @answer.save
LazyDoer.perform_async(@question_owner,current_user,@answer,@question)
redirect_to question_path(@question), notice: "Answer was successfully created."
else
render(:template => "questions/show", alert: "There was an error when adding answer.")
end
end
Hier haben Sie meinen Arbeiter:
class LazyDoer
include Sidekiq::Worker
sidekiq_options retry: false
def perform(question_owner,current_user,answer,question)
@question_owner = question_owner
@current_user = current_user
@answer = answer
@question = question
UserMailer.send_email(@question_owner,@current_user,@answer,@question).deliver
end
end
BEARBEITEN:
Ich habe meinen LazyDoer-Worker voll funktionsfähig gemacht, aber jetzt habe ich Probleme damit, E-Mails darüber zu senden.Was ist das Wichtigste, MAILER FUNKTIONIERT PERFEKT OHNE SIDEKIQ.Hier ist der Fehler in sidekiq:
2014-07-30T19:28:38.479Z 4317 TID-amn3w LazyDoer JID-3e465606b1d5728181002af0 INFO: start
2014-07-30T19:28:38.480Z 4317 TID-amn3w LazyDoer JID-3e465606b1d5728181002af0 INFO: fail: 0.001 sec
2014-07-30T19:28:38.481Z 4317 TID-amn3w WARN: {"retry"=>false, "queue"=>"default", "class"=>"LazyDoer", "args"=>["matthew.kilan@gmail.com", "matthew.kilan@gmail.com", "#<Answer:0x000000045fd148>", "#<Question:0x000000045fe728>"], "jid"=>"3e465606b1d5728181002af0", "enqueued_at"=>1406748518.4762628}
2014-07-30T19:28:38.481Z 4317 TID-amn3w WARN: undefined method `email' for "matthew.kilan@gmail.com":String
2014-07-30T19:28:38.481Z 4317 TID-amn3w WARN: /home/mateusz/Pulpit/Aptana3_Workspace/challenge_app/app/mailers/user_mailer.rb:9:in `send_email'
Und hier ist mein Mailer:
class UserMailer < ActionMailer::Base
default from: "matthew.kilan@gmail.com"
def send_email(question_owner,cur_user,answer,question)
@question_owner = question_owner
@cur_user = cur_user
@answer = answer
@question = question
mail(to: @question_owner.email, subject: "Answer added to your question:")
end
def accepted_email(user,answer,question)
@user = user
@answer = answer
@question = question
mail(to: @user.email, subject: "Your answer has been accepted")
end
end
Lösung
Ich habe eine Lösung, das Problem mit dem Sidekiq-Fehler bestand darin, dass Redis komplexe Rails-Daten, wie zum Beispiel ActiveRecord-Modelle, nicht richtig verstehen kann, da Redis die NOSQL-Datenbank verwendet, wenn Sie versuchen, sie an Ihren Worker, sagen wir, den gesamten Benutzer zu senden mit jedem einzelnen Attribut, das er hat – das wird in Redis nicht funktionieren, die Daten sind viel zu komplex.Die Lösung ist einfach: Schauen Sie sich Ihre generierte E-Mail-Ansicht und mailer.rb genau an und sehen Sie genau, welche Attribute Sie benötigen. Wenn Sie dann Ihren Mitarbeiter anrufen müssen, senden Sie ihm NUR diese Attribute, nicht ganze ActiveRecord-Modelle.
Hier haben Sie einen festen Arbeiter:
class LazyDoer
include Sidekiq::Worker
sidekiq_options retry: false
def perform(question_owner_email,current_user_name,answer_contents,question_title)
UserMailer.send_email(question_owner_email,current_user_name,answer_contents,question_title).deliver
end
end
Fester Controller (WICHTIGSTES):
class AnswersController < ApplicationController
before_action :authenticate_user!
before_action :set_question, except: [:adding_likes,:accept]
def create
@answer = Answer.new(answer_params)
@answer.user_id = current_user.id
@answer.question_id = @question.id
@question_owner = User.find(@question.user_id)
if @answer.save
LazyDoer.perform_async(@question_owner.email,current_user.name,@answer.contents,@question.title)
#DLA MAILERA BEZ SIDEKIQ UserMailer.send_email(@question_owner,current_user,@answer,@question).deliver
redirect_to question_path(@question), notice: "Answer was successfully created."
else
#redirect_to question_path(@question), alert: "There was an error when adding answer."
render(:template => "questions/show", alert: "There was an error when adding answer.")
end
end
end
Benutzer-Mailer behoben:
class UserMailer < ActionMailer::Base
default from: "matthew.kilan@gmail.com"
def send_email(question_owner_email,cur_user_name,answer_contents,question_title)
@question_owner_email = question_owner_email
@cur_user_name = cur_user_name
@answer_contents = answer_contents
@question_title = question_title
mail(to: @question_owner_email, subject: "Answer added to your question:")
end
end
E-Mail-Ansicht korrigiert (mit Verwendung einer schlanken Vorlagensprache anstelle von erb):
doctype html
html
head
meta content="text/html; charset=UTF-8" http-equiv="Content-Type"
body
h1 Your question #{@question_title} has been answered
p
|
Answered by #{@cur_user_name}
<br />
The answer content is:
<br />
#{@answer_contents}
p Accept or like the answer if it was useful for you.
Andere Tipps
Anstatt ein Benutzerobjekt in @question_owner zu senden, senden Sie die Benutzer-ID.