Error with after_destroy_commit using broadcast_replace_later_to with Turbo Streams

359 views Asked by At

iv been tryna implement turbo streams with friend request system and i have the following code in place:

 # models/friend_request.rb
  after_create_commit do 
    broadcast_friend_request_form_replace
  end
  
  after_destroy_commit do 
    broadcast_friend_request_form_replace
  end
 
  private
 
  def broadcast_friend_request_form_replace
    # Sends a replace broadcast to the Sender's stream, targeting the Receiver's turbo frame to perform the form changes.
    broadcast_replace_later_to [self.sender.id, self.receiver.id], target: dom_id(self.receiver), partial: "users/friend_request_form", 
      locals: { logged_in_user: self.sender, user: self.receiver, friend_request: self }
 
    # Sends a replace broadcast to the Receiver's stream, targeting the Sender's turbo frame to perform the form changes.
    broadcast_replace_later_to [self.receiver.id, self.sender.id], target: dom_id(self.sender), partial: "users/friend_request_form", 
      locals: { logged_in_user: self.receiver, user: self.sender, friend_request: self }
  end

The feature works with after_create_commit callback, however im having this error when trying to do it for the after_destroy_commit callback: Discarded Turbo::Streams::ActionBroadcastJob due to a ActiveJob::DeserializationError.

To my understanding, the error maybe related to the fact that, since im using broadcast_replace_later_to instead of broadcast_replace_to, it enqueues a background job to be done at a later time and when that happens the object (self) no longer exists and therefore I'm receiving the DeserializationError error.

I have tried using broadcast_replace_to instead but that makes it synchronous and what happens is that only the first callback executed after a page refresh/reload will work, not both.

1

There are 1 answers

0
zjeraar On

Yes you are right, the reason is indeed that the object no longer exists. You can do it however. Just create the job directly like this:

after_destroy_commit do
  Turbo::Streams::ActionBroadcastJob.perform_later(stream, action:, target:, **rendering)
end

See https://www.rubydoc.info/gems/turbo-rails/0.5.2/Turbo/Streams/ActionBroadcastJob#perform-instance_method