Bur*_*men 2 ruby-on-rails delayed-job rails-activejob
我需要在后台标记一组消息(我正在使用delayed_job gem)因为前景需要一些时间.所以我创建了一个ActiveJob类MarkMessagesAsReadJob,并传递了它user和messages变量,以便标记所有的messages读取user.
// passing the values in the controller
@messages = @conversation.messages
MarkMessagesAsReadJob.perform_later(current_user, @messages)
Run Code Online (Sandbox Code Playgroud)
在我的ActiveJob类中,我执行任务.
// MarkMessagesAsReadJob.rb
class MarkMessagesAsReadJob < ActiveJob::Base
queue_as :default
def perform(user, messages)
messages.mark_as_read! :all, :for => user
end
end
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试执行任务时,我收到错误 ActiveJob :: SerializationError(不支持的参数类型:ActiveRecord :: Associations :: CollectionProxy):
我读到我们只能将支持的类型传递给ActiveJob,我认为它无法序列化CollectionProxy对象.我该如何解决/修复此问题?
PS:我考虑过了
@messages.map { |message| MarkMessagesAsReadJob.perform_later(current_user, message) }
Run Code Online (Sandbox Code Playgroud)
但是我觉得一个接一个地标记它们非常昂贵.
我认为简单的方法是将消息ID传递给perform_later()方法,例如:
在控制器中:
@messages = @conversation.messages
message_ids = @messages.pluck(:id)
MarkMessagesAsReadJob.perform_later(current_user, message_ids)
Run Code Online (Sandbox Code Playgroud)
并用于ActiveJob:
def perform(user, message_ids)
messages = Message.where(id: ids)
messages.mark_as_read! :all, :for => user
end
Run Code Online (Sandbox Code Playgroud)
小智 6
对于较大的数据集,传递 message_ids 是不切实际的。相反,传递消息的 SQL:
@messages = @conversation.messages
MarkMessagesAsReadJob.perform_later(current_user, @messages.to_sql)
Run Code Online (Sandbox Code Playgroud)
然后从作业中查询它们:
class MarkMessagesAsReadJob < ActiveJob::Base
queue_as :default
def perform(user, messages_sql)
messages = Message.find_by_sql(messages_sql)
messages.mark_as_read! :all, :for => user
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1830 次 |
| 最近记录: |