Refresh broadcasts generated without changes
aprescott opened this issue · 0 comments
Suppose User
broadcasts refreshes:
class User < ApplicationRecord
broadcasts_refreshes
end
Currently, a broadcast is generated by User.last.save!
, even though there are no changes to the model or the database. With many save!
calls across models that aren't actually changed, this can result in lots of seemingly wasteful jobs.
There seems to be clear solution to this that doesn't involve reimplementing broadcasts_refreshes
and setting up the same *_commit
callbacks manually:
For example, there's no callback mechanism (like a sort of around_commit
) to wrap the code in suppressing_turbo_broadcasts {}
. Moreover, User.last.touch
should fire a change, so inspecting, e.g., has_changes_to_save?
isn't quite correct. There's a gem, ar_transaction_changes, which helps with this.
It'd be great to have a simple way to do this!
A sort-of workaround using the ar_transaction_changes gem, but it feels a little hacky (also note it relies on Rails 7.1's callback ordering behavior):
def self.broadcasts_refreshes_when_changed
after_update_commit :suppress_broadcasts_if_no_changes
broadcasts_refreshes
after_update_commit :restore_broadcasts
end
def suppress_broadcasts_if_no_changes
@__original_turbo_broadcasts_suppressed = self.class.suppressed_turbo_broadcasts
self.class.suppressed_turbo_broadcasts = true if transaction_changed_attributes.blank?
end
def restore_broadcasts
self.class.suppressed_turbo_broadcasts = @__original_turbo_broadcasts_suppressed
end