5

フォアグラウンドで時間がかかるため、バックグラウンドでメッセージのコレクションをマークする必要があります (delayed_job gem を使用しています)。だから私はActiveJobクラスを作成し、それと変数MarkMessagesAsReadJobを渡してuser、すべての読み取りをマークしました。messagesmessagesuser

// passing the values in the controller
@messages     = @conversation.messages
MarkMessagesAsReadJob.perform_later(current_user, @messages) 

私の ActiveJob クラスでは、タスクを実行します。

// MarkMessagesAsReadJob.rb
class MarkMessagesAsReadJob < ActiveJob::Base
  queue_as :default

  def perform(user, messages)
    messages.mark_as_read! :all, :for => user
  end
end

ただし、タスクを実行しようとすると、エラー ActiveJob::SerializationError (Unsupported argument type: ActiveRecord::Associations::CollectionProxy) が発生しました:

サポートされている型のみを ActiveJob に渡すことができると読みましたが、CollectionProxy オブジェクトをシリアル化できないと思います。これを回避/修正するにはどうすればよいですか?

PS:考えました

@messages.map { |message| MarkMessagesAsReadJob.perform_later(current_user, message) } 

しかし、それらを1つずつマークするのはかなり高価だと思います。

4

3 に答える 3

4

ジョブは後で実行されるため、コレクションの代わりにパラメーターとして id を渡す必要があると思います

ActiveJob にはシリアライズ パラメータが必要であり、パラメータ タイプがサポートされていない場合は SerializationError がスローされます http://api.rubyonrails.org/classes/ActiveJob/SerializationError.html

元:

@message_ids = @conversation.messages.pluck(:id)
# use string if array is not supported
# @message_ids = @message_ids.join(", ")
MarkMessagesAsReadJob.perform_later(current_user, @message_ids) 

次に、それらのメッセージを再度クエリしてマークします

class MarkMessagesAsReadJob < ActiveJob::Base
  queue_as :default
  def perform(user, message_ids)
    # use string if array is not supported
    # message_ids = message_ids.split(",").map(&:to_i)
    messages = Message.where(id: message_ids) #change this to something else
    messages.mark_as_read! :all, :for => user
  end
end

テストされていません。問題ないことを願っています

于 2015-08-22T09:33:20.140 に答える