The common pattern for interfacing with ActionJob
in Rails is to set up a Job with a perform()
method that gets called asynchronously via perform
In addition to what Daniel Batalla wrote, here's one more observation that I made: deliver_later
seems to perform lazy evaluation, while deliver_now
does not.
I have an ActiveRecord model with an additional attribute reset_token
that is not stored in the database (this is from Michael Hartl's railstutorial.org; the model stores a hashed version of the token in the reset_digest
column).
When executing deliver_now
, accessing the @model
's reset_token
attribute inside the mailer view yields the reset token as expected. However, when executing deliver_later
, @model.reset_token
is always nil
. It appears as if deliver_later
updates the model with database data, and because reset_token
is an additional attribute that is not backed by the database, it will be nil
at that point. (The code documentation is too deeply nested for me to be able to verify this in the source.)
Michael uses deliver_now
in the tutorial. I don't know he does this to avoid lazy evaluation. But it took me a while to realize that I just had to change deliver_later
to deliver_now
to make my tests pass.
As you say in your question, deliver_now
does not use ActiveJob
.
Basically, deliver_later
is asynchronous. When you use this method, the email is not send at the moment, but rather is pushed in a job's queue. If the job is not running, the email will not be sent. deliver_now
will send the email at the moment, no matter what is the job's state. Here you can see the documentation for deliver
methods.
According to your second question, perform_now
will process the job immediately without sending to the queue. perform_later
, however, will add the job to the queue, and as soon the job's queue is free, will perform the job. Here you can see the documentation for perform
methods.