I need to mark a collection of messages at the background (I am using delayed_job gem) since it takes some time on the foreground. So I've created an ActiveJob
class MarkMessagesAsReadJob
, and passed it user
and messages
variables in order to mark all of the messages
read for user
.
// passing the values in the controller
@messages = @conversation.messages
MarkMessagesAsReadJob.perform_later(current_user, @messages)
and in my ActiveJob class, I perform the task.
// MarkMessagesAsReadJob.rb
class MarkMessagesAsReadJob < ActiveJob::Base
queue_as :default
def perform(user, messages)
messages.mark_as_read! :all, :for => user
end
end
However, when I tried to perform the task, I got the error ActiveJob::SerializationError (Unsupported argument type: ActiveRecord::Associations::CollectionProxy):
I read that we can only pass supported types to the ActiveJob, and I think it can not serialize the CollectionProxy object. How can I workaround/fix this?
PS: I considered
@messages.map { |message| MarkMessagesAsReadJob.perform_later(current_user, message) }
however I think marking them one by one is pretty expensive .
I think the easy way is pass message ids to the perform_later()
method, for example:
in controller:
@messages = @conversation.messages
message_ids = @messages.pluck(:id)
MarkMessagesAsReadJob.perform_later(current_user, message_ids)
And use it in ActiveJob
:
def perform(user, message_ids)
messages = Message.where(id: message_ids)
messages.mark_as_read! :all, :for => user
end