具有自定义属性的延迟作业 [英] Delayed job with custom attributes

查看:96
本文介绍了具有自定义属性的延迟作业的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ActiveRecord和Rails 3.2.3中使用了延迟作业3.0.2。我有一个使用has_secure_password mixin的用户模型,因此密码仅以加密方式存储。现在,我想使用延迟的作业来发送欢迎电子邮件,该电子邮件应包含未加密密码的副本。

I'm using delayed job 3.0.2 with ActiveRecord and Rails 3.2.3. I have a User model which uses the has_secure_password mixin, so the password is only stored encrypted. Now I want to use delayed job to send the welcome email, which should contain a copy of the unencrypted password.

创建记录时,纯文本密码位于User#password中。但是,延迟的工作似乎仅对记录的ID进行序列化/反序列化,并通过执行User.find(X)创建模型的新实例。这样,我的纯文本密码就会丢失,并且用户的电子邮件中会得到一个空密码。

When creating the record, the plain-text password is in User#password. But delayed job seems to serialize/ deserialize the id of the record only and create a new instance of the model by doing User.find(X). This way my plain-text password is lost and the user gets an empty password in his email.

我如何告诉延迟作业序列化/反序列化自定义的虚拟属性,也不会存储在数据库中吗?

How can I tell delayed-job to serialize/ deserialize custom "virtual" attributes too, which are not stored in the database otherwise?

这是我的延迟工作2.x的猴子补丁,效果很好。

This is my monkey patch for delayed job 2.x, which worked fine.

class ActiveRecord::Base
  def self.yaml_new(klass, tag, val)
    klass.find(val['attributes']['id']).tap do |m|
      val.except("attributes").each_pair{ |k, v| m.send("#{k}=", v) }
    end
  rescue ActiveRecord::RecordNotFound
    raise Delayed::DeserializationError
  end
end

它不适用于延迟的工作3.x。我也不太希望修复猴子补丁,因为我<希望> 对此有一个合适的解决方案

It doesn't work with delayed job 3.x. I'm also not really interested in fixing my monkey patch as I hope there's a proper solution to this.

推荐答案

在延迟作业3.x中,最好的方法是重写ActiveRecord类上的一些方法,然后强制Psych YAML反序列化器从序列化数据。默认情况下,延迟的作业仅使用反序列化的ID,然后从数据库加载ActiveRecord对象。因此,假设我有一个称为ShipmentImport的ActiveRecord类,并且我想要一个名为 user_id的attr_accessor与延迟的作业序列化/反序列化一起使用。这是我会做的。

In delayed job 3.x, the best way to do this is to override a few methods on your ActiveRecord class, and then to force the Psych YAML deserializer to load the ActiveRecord object from the serialized data. By default, delayed job uses just the deserialized id, and then loads the ActiveRecord object from the DB. So, say I have an ActiveRecord class called ShipmentImport, and I want an attr_accessor named 'user_id' to work with delayed job serialization/deserialization. Here is what I would do.

在ShipmentImport ActiveRecord类中,添加以下内容:

In the ShipmentImport ActiveRecord class, add this:

def encode_with(coder)
  super
  coder['user_id'] = @user_id
end

def init_with(coder)
 super
  @user_id = coder['user_id']
  self
end

在应用程序的初始化程序中,将其添加到ActiveRecord类中:

In an initializer for your application, add this for your ActiveRecord class:

Psych.load_tags[['!ruby/ActiveRecord', ShipmentImport.name].join(':')] = ShipmentImport

这篇关于具有自定义属性的延迟作业的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆