Created
October 15, 2024 07:34
-
-
Save swombat/283c86d308373c24f190b62748a6f6c0 to your computer and use it in GitHub Desktop.
ActivePage workaround to get cable-like refreshes of complex pages without having a thousand `cable_ready_updates_for` blocks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActiveChildren | |
extend ActiveSupport::Concern | |
included do | |
class_attribute :active_children, default: [] | |
after_save :notify_active_children | |
end | |
class_methods do | |
def has_active_child(name) | |
self.active_children << name | |
end | |
def has_active_children(*names) | |
self.active_children.concat(names) | |
end | |
end | |
def notify_active_children | |
self.class.active_children.each do |child_name| | |
children = self.send(child_name) | |
children.each do |child| | |
ActionCable.server.broadcast(child.cable_ready_channel_name, { parent_changed: true }) | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Client < ApplicationRecord | |
incldue ActiveChildren | |
has_many :claims, dependent: :destroy, enable_cable_ready_updates: true | |
has_many :grants, dependent: :destroy, enable_cable_ready_updates: true | |
has_many :enquiries, dependent: :destroy, enable_cable_ready_updates: true | |
# Notify all the children in these collections when the client object updates | |
has_active_children :claims, :grants, :enquiries | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Controller } from "@hotwired/stimulus" | |
import consumer from "../channels/consumer" | |
export default class extends Controller { | |
static targets = ["field"]; | |
static values = { | |
channel: String, | |
identifier: String, | |
clearChannel: String, | |
debug: Boolean | |
}; | |
channels = []; | |
connect() { | |
this.logIfDebugging("Connecting to ActivePageController"); | |
this.channels.push(consumer.subscriptions.create({ | |
channel: "CableReady::Stream", | |
identifier: this.channelValue | |
}, { | |
received: (data) => { | |
this.logIfDebugging("Received data:", data); | |
Turbo.visit(window.location.href, { action: "replace" }); | |
}, | |
connected: () => { | |
this.logIfDebugging("Successfully connected to stream:", this.channelValue, this.identifierValue); | |
}, | |
rejected: () => { | |
this.logIfDebugging("Subscription to stream was rejected:", this.channelValue, this.identifierValue); | |
}, | |
disconnected: () => { | |
this.logIfDebugging("Disconnected from stream:", this.channelValue, this.identifierValue); | |
} | |
})); | |
} | |
disconnect() { | |
this.logIfDebugging("Disconnecting from ActivePageController"); | |
this.channels.forEach(channel => { | |
this.logIfDebugging("Unsubscribing from channel:", channel); | |
channel.unsubscribe(); | |
}); | |
this.logIfDebugging("Disconnected from ActivePageController", this.channelValue, this.clearChannelValue, this.identifierValue); | |
} | |
logIfDebugging(...args) { | |
if (this.debugValue) { | |
console.log(...args); | |
} | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActivePageHelper | |
def active_page(object, debug: false) | |
turbo_frame_tag "active-page-#{object.class.name.underscore}-#{object.id}", refresh: "morph" do | |
content_tag(:div, "", data: { controller: "active-page", active_page_channel_value: signed_stream_identifier(object.cable_ready_channel_name), active_page_clear_channel_value: object.cable_ready_channel_name, active_page_identifier_value: object.id, active_page_debug_value: debug }) do | |
yield | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%= active_page(@my_object) do %> | |
... | |
You may need further turbo-frames inside to delimit things | |
... | |
<% end %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh I forgot that there is also this model method I've added to ApplicationRecord: