2015-07-10 46 views
0

所以我有一些電子郵件沒有出去,因爲沒有實例化郵件服務API密鑰。但是,詳細信息模型對象被保存在數據庫中。我不想在數據庫中重新創建它們。我可以發送delayed_job一個內存中唯一的ActiveRecord對象嗎?

我編寫了一個rake任務來發送電子郵件,並且它更容易嘗試創建一些臨時內存中對象,而不是嘗試根據detail_params中的內容找到正確的ActiveRecord對象。然後,我用DetailMailerJob發送的電子郵件,並通過在實例化詳細對象。

temp_obj = Detail.new(detail_params) 
    DetailMailerJob.new.delay.notify_job(temp_obj) 

但我運行rake任務後,注意到在延遲:: Job.all隊列以下錯誤:

last_error: "ActiveRecord::RecordNotFound 

這是否意味着只辦法,我在通詳細對象爲DetailMailerJob是先找到數據庫實例化的記錄? (即,沒有在內存中的對象)

編輯:這裏是DetailMailer & DetailMailerJob類。

class DetailMailerJob 
     def notify_job(detail) 
     DetailMailer.notify_job(detail).deliver 
     end 
    end 


class DetailMailer < ActionMailer::Base 
    def notify_job(detail) 
    @detail = detail 
    @emailed_to = detail.emailed_to.join(", ") 
    mail(to: detail.emailed_to, subject: "#{detail.full_name} - New Message") 
    end 
end 
+0

如果不知道「DetailMailerJob」中有什麼,就不可能回答這個問題。這就是產生錯誤的原因! – Gene

+0

感謝您的建議基因。更新。 – Nona

回答

1

我也遇到過這個問題。這是對DJ的優化,使用ActiveRecord::Base的已保存版本的子類,而不是將全部內容再次保存在DJ隊列中。我相信他們這樣做是因爲AR的實例可能很大。

如果你定義一個相同的感興趣的領域DetailActiveRecord::Base繼承了一個新類。喜歡的東西:

temp_obj = DetailAsAPlainOldRubyObject.new(detail_params) 
DetailMailerJob.new.delay.notify_job(temp_obj) 

更多細節:

class DetailAsAPlainOldRubyObject 
    attr_accessor :field_a, :field_b, ... 

    def initialize(params) 
    self.field_a = params['field_a'] 
    self.field_b = params['field_b'] 
    ... 
    end 
end 

現在用一個實例啓動作業延遲的工作 - 特別是方法delay - 作品存儲類的self(在你的榜樣DetailMailerJob),方法的名稱(notify_job)以及數據庫表中參數的序列化表示。工作進程從表中出列記錄,反序列化參數,並調用該類的方法。

的問題是序列化。 DJ用特殊的serializer for ActiveRecord來擴充YAML,它只編碼錶名和主鍵。反序列化導致表中的find。我想他們這樣做是爲了節省數據庫空間和時間。當然,這個技巧只有在ActiveRecord已被保存時纔有效。 (IMO它會很酷,如果DJ跳過棘手的系列化如果記錄尚未保存,但可惜事實並非如此。)

在上面的鏈接請注意,在你的代碼的錯誤信息!它被用於當find失敗時引發的異常。

通過使用普通的對象沒有ActiveRecord基地,你應該得到正常的YAML序列化的字符串。

相關問題