I’m trying to delay the increment on a column (yest_shareholder_count) by one day whenever an investment is created in order to keep a record of the number of users that had an investment in a venture one day ago (so I can use this data to produce graphs tracking the number of investors over time).
I figured the simplest way to do this would be to use delayed_job, but this isn’t working. The delayed_job is created in a separate table and, according to the SQLite DB Browser, it is run one day later. But the yest_shareholder_count column is not being incremented.
Venture Model:
def yest_increment
self.increment!(:yest_shareholder_count)
end
handle_asynchronously :yest_increment, :run_at => Proc.new {1.minute.from_now}
Investments Controller:
def create
@venture = Venture.find(params[:share_id])
@venture_increment= @venture.increment(:shareholder_count)
@venture_yest_increment= @venture.yest_increment
@investment = current_user.invest!(@venture)
if @venture_increment.save and @venture_yest_increment.save
respond_to do |format|
format.html {redirect_to @venture}
end
end
end
The straightforward increment happens as it should, but the delayed increment never does.
These are the contents of the “handler” column in the delayed_jobs table, just in case they are useful:
--- !ruby/struct:Delayed::PerformableMethod
object: !ruby/ActiveRecord:Venture
attributes:
created_at: 2011-06-21 07:00:12.252808
onemth_shareholder_count: 0
updated_at: 2011-08-09 16:50:36.864354
onewk_shareholder_count: 0
shareholder_count: 4
id: 49
user_id: 40
yest_shareholder_count: 0
method_name: :yest_increment_without_delay
args: []
I’m not sure where the “yest_increment_without_delay” is coming from, or why “args” is blank…
Any help much appreciated.
EDIT: I have “1.minute.from_now” rather than “1.day.from_now” just to test the code.
When you define a method to be handled asynchronously using delayed job, delayed job creates an alias method chain(which I am not very familiar with). It leads to calls original method name handled by delayed job, and when delayed job gets around to it, it calls the original_method_name_without_delay, which is the actual objects method aliased.
There are no arguments as you didn’t pass any arguments to
yest_increment. If you pass any arguments toyest_incrementthey will be saved along with the job, to be passed on to actual method when delayed job calls it.The object in the table is the serialized version of the object, delayed_job stores in db. When job needs to be run, it will create a object by deserializing this and call the method with given arguments on it. As the object is an ActiveRecord object, de-serialization involves, retrieving id from serialized object and finding the object from database.
As per your actual problem, that it is not working, it is not clear what is not working. Does the delayed job is not getting called or the value is not getting incremented or the delayed_job gets called too soon. If its the last one, changing your code to following might help: