Rails 3:Mail ::序列化后无法传递消息

时间:2011-05-12 18:31:46

标签: ruby-on-rails-3 yaml actionmailer

我想序列化一个Mail::Message对象,以便将其存储在数据库中并稍后发送。 我的第一次尝试是使用ActiveRecord的内置serialize方法,如下所示:

class Email < ActiveRecord::Base
  serialize :mail

  # ...

end

不幸的是,尝试保存记录会导致异常

> foo.save
ArgumentError: wrong number of arguments (1 for 0)
from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/mail-2.2.19/lib/mail/message.rb:1714:in `to_yaml'
from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:55:in `accept'
from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:36:in `<<'
from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/psych.rb:165:in `dump'
from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/activerecord-3.0.7/lib/active_record/base.rb:1720:in `block in arel_attributes_values'
    (...)

所以我只是使用to_yaml的{​​{1}} / from_yaml函数创建了一个自定义访问器。但现在我遇到了这种奇怪的行为:

Mail::Message

有关如何解决此问题的任何想法?为什么将对象序列化为yaml会使mail_original = UserMailer.user_welcome_email(@user) => #<Mail::Message:93415800, Multipart: false, Headers: <From: (...) >, <To: (...) >, <Subject: (...) >, <Mime-Version: 1.0>, <Content-Type: text/plain>> mail_clone = Mail::Message.from_yaml mail_original.to_yaml => #<Mail::Message:92940980, Multipart: false, Headers: <Date: (...) >, <From: (...) >, <To: (...) >, <Message-ID: (...) >, <Subject: (...) >, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: quoted-printable>> mail_original.deliver => #<Mail::Message:93415800, Multipart: false, Headers: <Date: (...) >, <From: (...) >, <To: (...) >, <Message-ID: (...) >, <Subject: (...) >, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: quoted-printable>> mail_clone.deliver Errno::ECONNREFUSED: Connection refused - connect(2) from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:546:in `initialize' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:546:in `open' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:546:in `tcp_socket' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:555:in `block in do_start' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/timeout.rb:57:in `timeout' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/timeout.rb:87:in `timeout' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:555:in `do_start' from /home/akrueger/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/smtp.rb:525:in `start' from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/mail-2.2.19/lib/mail/network/delivery_methods/smtp.rb:128:in `deliver!' from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/mail-2.2.19/lib/mail/message.rb:1989:in `do_delivery' from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/mail-2.2.19/lib/mail/message.rb:232:in `deliver' from (irb):68 from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands/console.rb:44:in `start' from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands/console.rb:8:in `start' from /home/akrueger/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.7/lib/rails/commands.rb:23:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>' 对象无法传递?是否有其他方法可以正确序列化Message对象以便稍后发送?

2 个答案:

答案 0 :(得分:3)

我意识到mail_clone对象没有正确的传递设置,导致deliver调用失败。浏览Rails源代码,我找到了以下解决方案:

mail_clone = Mail::Message.from_yaml mail_original.to_yaml
ActionMailer::Base.wrap_delivery_behavior mail_clone
mail_clone.deliver

因此,这可能是序列化Mail::Message对象的一种方法:

class Email < ActiveRecord::Base
  def mail
    @mail_cached || begin
      m = Mail::Message.from_yaml(self.read_attribute :mail)
      ActionMailer::Base.wrap_delivery_behavior m
      m
    rescue
      nil
    end
  end

  def mail=(val)
    @mail_cached = val
    write_attribute :mail, val.to_yaml
  end

  # ...
end

答案 1 :(得分:0)

指定班级名称有帮助吗?

serialize :mail, 'Mail::Message'