Reputation: 4762
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.
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?
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
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.
Upvotes: 3
Views: 1378
Reputation: 539
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.
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
In an initializer for your application, add this for your ActiveRecord class:
Psych.load_tags[['!ruby/ActiveRecord', ShipmentImport.name].join(':')] = ShipmentImport
Upvotes: 2