ActionCable: the part of Rails I find at the same time very cool, and a component I’m never eager to develop around.
In app specs, I’ll often write what endpoints I’ll be needing. GET /plants
, POST /friends
, and so on. And I’ll often write something to the effect of “LIVE /friends/:id
”. What I mean by that: given an endpoint which gives live updates about the status of [resource]
—in this example, a Friend
record.
Looking at the ActionCable guide,—and I say this with a lot of understanding that it’s still relatively young—it’s as if the conventions we know didn’t exist. All the sadder knowing that in controller-land, conventions about “resources” are already there for free, and make us that much efficient!
I’d like to see better conventions about getting live updates on resources. Ordinary singular resources, but also with an array of them, sometimes a scope of records, associated records on X, and so on.
In my new app, I tried the approach for updates on a single record. I must say that for now, I quite like it.
Some simplified code below, but the gist is:
- Model broadcasts itself to channel after commits
- Channel transmits record as json
- Client can subscribe to updates as an event
Which allows my front-end code to just call:
sub = cable.subscriptions.create(
{channel: 'FriendChannel', id: 1},
{received: (friend) => useInDomOrWhatever(friend)}
)
And I get free updates.
class FriendChannel < ApplicationCable::Channel
def subscribed
stream_for friend
transmit friend.as_json
end
private
def friend
@friend ||= Friend.find(params[:id])
end
end
class Friend < ApplicationRecord
after_update_commit :transmit_update
def transmit_update
FriendChannel.broadcast_to(self, self.as_json)
end
I think an approach like this could simplify development of interfaces with live views.
I haven’t tested out live-viewing collections/scopes yet, but I’m looking forward to see how conventions can simplify that too.