Dan*_*G2k 15 ruby-on-rails rails-activejob
我正在尝试使用Rails 4.2的deliver_later方法设置联系表单.但是,我只能让deliver_now工作,因为deliver_later正在尝试序列化我的对象并且每次都失败.
这是我的设置:
messages_controller.rb
class MessagesController < ApplicationController
def new
@message = Message.new
end
def create
@message = Message.new(params[:message])
if @message.valid?
ContactMailer.contact_form(@message).deliver_later
redirect_to root_path, notice: "Message sent! Thank you for contacting us."
else
render :new
end
end
end
Run Code Online (Sandbox Code Playgroud)
contact_mailer.rb
class ContactMailer < ApplicationMailer
default :to => Rails.application.secrets['email']
def contact_form(msg)
@message = msg
mail(:subject => msg.subject, from: msg.email)
end
end
Run Code Online (Sandbox Code Playgroud)
message.rb
class Message
include ActiveModel::Model
include ActiveModel::Conversion
## Not sure if this is needed ##
include ActiveModel::Serialization
extend ActiveModel::Naming
attr_accessor :name, :subject, :email, :body
validates_presence_of :email, :body
validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i
validates_length_of :body, :maximum => 1000
def initialize(attributes = {})
attributes.each { |name, value| send("#{name}=", value) }
end
## Not sure if this is needed ##
def attribtues
{'name' => nil, 'subject' => nil, 'email' => nil, 'body' => nil}
end
end
Run Code Online (Sandbox Code Playgroud)
我打电话时遇到的错误ContactMailer.contact_form(@message).deliver_later是:
ActiveJob::SerializationError in MessagesController#create
Unsupported argument type: Message
Extracted source (around line #10):
if @message.valid?
ContactMailer.contact_form(@message).deliver_later
redirect_to root_path, notice: "Message sent! Thank you for contacting us."
else
render :new
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望这是一个后台进程.我将尽快添加类似Sidekiq的东西,但我认为最好事先修复此序列化问题.
任何帮助表示赞赏!谢谢 :)
Jiř*_*šil 11
为了使用您的类ActiveJob(deliver_later委托给它),它需要能够通过其ID唯一地标识对象.此外,它需要在反序列化时通过ID找到它(在邮件程序/作业中不需要手动反序列化).
class Message
...
include GlobalID::Identification
...
def id
...
end
def self.find(id)
...
end
end
Run Code Online (Sandbox Code Playgroud)
ActiveRecord会为你提供这些方法,但由于你没有使用它,你需要自己实现它.由你来决定你想要存储记录的位置,但说实话,我认为通过使用ActiveRecord和下面的表格会更好.
一个简单的解决方案,避免必须使用ActiveRecord支持对象或创建不必要的表:
您也可以将消息参数传递给contact_form方法,然后在该方法中初始化Message对象,而不是将Message对象传递给contact_form方法.
这将解决问题而无需创建表,因为您正在初始化延迟作业工作者的内存空间中的对象.
例如:
messages_controller.rb
MessagesController < ApplicationController
def new
@message = Message.new
end
def create
@message = Message.new(params[:message])
if @message.valid?
ContactMailer.contact_form(params[:message]).deliver_later
redirect_to root_path, notice: "Message sent! Thank you for contacting us."
else
render :new
end
end
end
Run Code Online (Sandbox Code Playgroud)
contact_mailer.rb
class ContactMailer < ApplicationMailer
default :to => Rails.application.secrets['email']
def contact_form(msg_params)
@message = Message.new(msg_params)
mail(:subject => msg.subject, from: msg.email)
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4699 次 |
| 最近记录: |