Erreur constante non initialisée de Rails 4 Sidekiq
-
21-12-2019 - |
Question
J'ai un problème avec ma candidature, lorsque j'essaie d'envoyer des e-mails en arrière-plan, j'obtiens une erreur uninitialized constant AnswersController::LazyDoer
, je n'ai aucune idée de pourquoi ça ne fonctionne pas, des suggestions ?
Mon travailleur est dans app/workers/lazy_doer.rb
Voici mon contrôleur :
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
Ici vous avez mon ouvrier :
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
MODIFIER:
J'ai rendu mon travailleur LazyDoer pleinement opérationnel, mais j'ai maintenant des problèmes pour envoyer des e-mails via celui-ci.Ce qui est le plus important, MAILER FONCTIONNE PARFAITEMENT SANS SIDEKIQ.Voici l'erreur à l'intérieur de 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'
Et voici mon mail :
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
La solution
J'ai une solution, le problème avec l'erreur Sidekiq était que, comme il utilise une base de données nosql qui est redis, redis ne peut pas comprendre correctement les données rails complexes, comme par exemple les modèles ActiveRecord, si vous essayez d'envoyer à votre travailleur, disons, l'utilisateur entier avec chaque attribut dont il dispose - cela ne fonctionnera pas dans Redis, les données sont beaucoup trop complexes.La solution est simple, regardez exactement votre vue de courrier électronique générée et mailer.rb et voyez exactement de quels attributs vous avez besoin, puis lorsque vous devez appeler votre travailleur, envoyez-lui UNIQUEMENT ces attributs, n'envoyez pas de modèles ActiveRecord entiers.
Ici vous avez un travailleur fixe :
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
Contrôleur fixe (LE PLUS IMPORTANT) :
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
Mail utilisateur fixe :
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
Affichage des e-mails fixe (avec utilisation d'un langage de modèle mince au lieu d'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.
Autres conseils
Au lieu d'envoyer l'objet utilisateur dans @question_owner, envoyez l'identifiant utilisateur.