سؤال

لدي مشكلة مع تطبيقي، عندما أحاول إرسال رسائل البريد الإلكتروني في الخلفية أحصل على خطأ uninitialized constant AnswersController::LazyDoer ليس لدي أدنى فكرة عن سبب عدم نجاحها، هل هناك أي اقتراحات؟

العامل عندي موجود app/workers/lazy_doer.rb

هنا وحدة التحكم الخاصة بي:

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

هنا لديك عاملي:

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

يحرر:

لقد جعلت عامل LazyDoer الخاص بي يعمل بكامل طاقته، ولكن الآن أواجه مشكلة في إرسال البريد الإلكتروني عبره.ما هو الأهم ، يعمل Mailer بشكل مثالي بدون SIDEKIQ.إليك الخطأ داخل 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'

وهنا لديك البريد الخاص بي:

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
هل كانت مفيدة؟

المحلول

لدي حل، مشكلة خطأ Sidekiq هي أنه نظرًا لأنه يستخدم قاعدة بيانات nosql وهي redis، لا يستطيع redis فهم بيانات القضبان المعقدة بشكل صحيح، مثل نماذج ActiveRecord على سبيل المثال، إذا كنت تحاول إرسالها إلى العامل الخاص بك، فلنفترض، المستخدم بالكامل مع كل سمة لديه - لن ينجح هذا في redis، فالبيانات معقدة للغاية.الحل بسيط، انظر بالضبط إلى عرض البريد الإلكتروني الذي تم إنشاؤه وmailer.rb وتعرف بالضبط على السمات التي تحتاجها، ثم عندما تحتاج إلى الاتصال بالموظف الخاص بك، أرسل له تلك السمات فقط، ولا ترسل نماذج ActiveRecord بأكملها.

هنا لديك عامل ثابت:

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

وحدة التحكم الثابتة (الأهم):

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

بريد المستخدم الثابت:

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

عرض البريد الإلكتروني الثابت (مع استخدام لغة القالب النحيفة بدلاً من 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.

نصائح أخرى

بدلاً من إرسال كائن المستخدم فيquestion_owner أرسل معرف المستخدم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top