How to set read attribute for broadcast-style notification with ActionCable Rails 5.2
I have a NotifyFollower model that sends out a broadcast to all people within the stream of ids that are the current_user's followers. The problem that I'm having is, the last notification will render every time the page is loaded, and instead of just once...I'm unsure of how to approach setting the notification to read when a user sees it & causing it not to reappear until the next update comes in. How can I configure actioncable to stop rendering the notification after a particular client sees it? I guess it shouldn't matter who sees it first on the stream, as long as it renders in view of the user. Last note, these notifications come in the form of alerts that show up for 3 seconds at most.
notify_follower.rb
class NotifyFollower < ApplicationRecord
belongs_to :user
after_create_commit do
PostNotifierRelayJob.perform_later(self)
end
# every 1000 records, activate job to delete old notifications
if self.count > 1000
def remove_old_notifications
DeleteOldNotificationsJob.perform_later(self.user)
end
end
end
_notify_follower.html.erb
<%= link_to posts_path, style: 'text-decoration: none;' do %>
<div class="alert alert-purple notify_follower post-alert-pos" role="alert">
<p><i class="far fa-bell"></i> <%= notify_follower.user.username %> <%= notify_follower.message %></p>
</div>
<% end %>
post_feed_notifier_relay_job.rb
class PostFeedNotifierRelayJob < ApplicationJob
queue_as :default
def perform(notify_follower)
ActionCable.server.broadcast 'post_channel', message: render_notify_follower(notify_follower)
end
private
def render_notify_follower(notify_follower)
ApplicationController.renderer.render(partial: 'notify_followers/notify_follower', locals: {notify_follower: notify_follower})
end
end
delete_old_notifications_job.rb
class DeleteOldNotificationsJob < ApplicationJob
queue_as :default
def perform(user)
pending_removal_ids = NotifyFollower.order('created_at DESC').limit(1000).pluck(user_id: user.id)
NotifyFollower.where(user_id: pending_removal_ids).where(notification_read: true).destroy_all
end
end
post_channel.rb
class PostChannel < ApplicationCable::Channel
def subscribed
stream_from "post_channel"
end
def unsubscribed
stop_all_streams
end
end
post_follower_notifier.coffee
App.post = App.cable.subscriptions.create "PostChannel",
connected: ->
disconnected: ->
received: (notify_follower) ->
# Called when there's an incoming data on the websocket for this channel
$(".post-notification-location").prepend "<div class='notify_follower'> #{notify_follower.message}</div>"
window.setTimeout (->
$('.alert').fadeTo(500, 0).slideUp 500, ->
$(this).remove()
return
return
), 5000
posts_controller.rb
def index
notify_followers_ids = current_user.following_users.pluck(:id)
@notify_followers = NotifyFollower.where(user_id: notify_followers_ids).order('created_at DESC')
end
javascript ruby-on-rails ruby actioncable
add a comment |
I have a NotifyFollower model that sends out a broadcast to all people within the stream of ids that are the current_user's followers. The problem that I'm having is, the last notification will render every time the page is loaded, and instead of just once...I'm unsure of how to approach setting the notification to read when a user sees it & causing it not to reappear until the next update comes in. How can I configure actioncable to stop rendering the notification after a particular client sees it? I guess it shouldn't matter who sees it first on the stream, as long as it renders in view of the user. Last note, these notifications come in the form of alerts that show up for 3 seconds at most.
notify_follower.rb
class NotifyFollower < ApplicationRecord
belongs_to :user
after_create_commit do
PostNotifierRelayJob.perform_later(self)
end
# every 1000 records, activate job to delete old notifications
if self.count > 1000
def remove_old_notifications
DeleteOldNotificationsJob.perform_later(self.user)
end
end
end
_notify_follower.html.erb
<%= link_to posts_path, style: 'text-decoration: none;' do %>
<div class="alert alert-purple notify_follower post-alert-pos" role="alert">
<p><i class="far fa-bell"></i> <%= notify_follower.user.username %> <%= notify_follower.message %></p>
</div>
<% end %>
post_feed_notifier_relay_job.rb
class PostFeedNotifierRelayJob < ApplicationJob
queue_as :default
def perform(notify_follower)
ActionCable.server.broadcast 'post_channel', message: render_notify_follower(notify_follower)
end
private
def render_notify_follower(notify_follower)
ApplicationController.renderer.render(partial: 'notify_followers/notify_follower', locals: {notify_follower: notify_follower})
end
end
delete_old_notifications_job.rb
class DeleteOldNotificationsJob < ApplicationJob
queue_as :default
def perform(user)
pending_removal_ids = NotifyFollower.order('created_at DESC').limit(1000).pluck(user_id: user.id)
NotifyFollower.where(user_id: pending_removal_ids).where(notification_read: true).destroy_all
end
end
post_channel.rb
class PostChannel < ApplicationCable::Channel
def subscribed
stream_from "post_channel"
end
def unsubscribed
stop_all_streams
end
end
post_follower_notifier.coffee
App.post = App.cable.subscriptions.create "PostChannel",
connected: ->
disconnected: ->
received: (notify_follower) ->
# Called when there's an incoming data on the websocket for this channel
$(".post-notification-location").prepend "<div class='notify_follower'> #{notify_follower.message}</div>"
window.setTimeout (->
$('.alert').fadeTo(500, 0).slideUp 500, ->
$(this).remove()
return
return
), 5000
posts_controller.rb
def index
notify_followers_ids = current_user.following_users.pluck(:id)
@notify_followers = NotifyFollower.where(user_id: notify_followers_ids).order('created_at DESC')
end
javascript ruby-on-rails ruby actioncable
add a comment |
I have a NotifyFollower model that sends out a broadcast to all people within the stream of ids that are the current_user's followers. The problem that I'm having is, the last notification will render every time the page is loaded, and instead of just once...I'm unsure of how to approach setting the notification to read when a user sees it & causing it not to reappear until the next update comes in. How can I configure actioncable to stop rendering the notification after a particular client sees it? I guess it shouldn't matter who sees it first on the stream, as long as it renders in view of the user. Last note, these notifications come in the form of alerts that show up for 3 seconds at most.
notify_follower.rb
class NotifyFollower < ApplicationRecord
belongs_to :user
after_create_commit do
PostNotifierRelayJob.perform_later(self)
end
# every 1000 records, activate job to delete old notifications
if self.count > 1000
def remove_old_notifications
DeleteOldNotificationsJob.perform_later(self.user)
end
end
end
_notify_follower.html.erb
<%= link_to posts_path, style: 'text-decoration: none;' do %>
<div class="alert alert-purple notify_follower post-alert-pos" role="alert">
<p><i class="far fa-bell"></i> <%= notify_follower.user.username %> <%= notify_follower.message %></p>
</div>
<% end %>
post_feed_notifier_relay_job.rb
class PostFeedNotifierRelayJob < ApplicationJob
queue_as :default
def perform(notify_follower)
ActionCable.server.broadcast 'post_channel', message: render_notify_follower(notify_follower)
end
private
def render_notify_follower(notify_follower)
ApplicationController.renderer.render(partial: 'notify_followers/notify_follower', locals: {notify_follower: notify_follower})
end
end
delete_old_notifications_job.rb
class DeleteOldNotificationsJob < ApplicationJob
queue_as :default
def perform(user)
pending_removal_ids = NotifyFollower.order('created_at DESC').limit(1000).pluck(user_id: user.id)
NotifyFollower.where(user_id: pending_removal_ids).where(notification_read: true).destroy_all
end
end
post_channel.rb
class PostChannel < ApplicationCable::Channel
def subscribed
stream_from "post_channel"
end
def unsubscribed
stop_all_streams
end
end
post_follower_notifier.coffee
App.post = App.cable.subscriptions.create "PostChannel",
connected: ->
disconnected: ->
received: (notify_follower) ->
# Called when there's an incoming data on the websocket for this channel
$(".post-notification-location").prepend "<div class='notify_follower'> #{notify_follower.message}</div>"
window.setTimeout (->
$('.alert').fadeTo(500, 0).slideUp 500, ->
$(this).remove()
return
return
), 5000
posts_controller.rb
def index
notify_followers_ids = current_user.following_users.pluck(:id)
@notify_followers = NotifyFollower.where(user_id: notify_followers_ids).order('created_at DESC')
end
javascript ruby-on-rails ruby actioncable
I have a NotifyFollower model that sends out a broadcast to all people within the stream of ids that are the current_user's followers. The problem that I'm having is, the last notification will render every time the page is loaded, and instead of just once...I'm unsure of how to approach setting the notification to read when a user sees it & causing it not to reappear until the next update comes in. How can I configure actioncable to stop rendering the notification after a particular client sees it? I guess it shouldn't matter who sees it first on the stream, as long as it renders in view of the user. Last note, these notifications come in the form of alerts that show up for 3 seconds at most.
notify_follower.rb
class NotifyFollower < ApplicationRecord
belongs_to :user
after_create_commit do
PostNotifierRelayJob.perform_later(self)
end
# every 1000 records, activate job to delete old notifications
if self.count > 1000
def remove_old_notifications
DeleteOldNotificationsJob.perform_later(self.user)
end
end
end
_notify_follower.html.erb
<%= link_to posts_path, style: 'text-decoration: none;' do %>
<div class="alert alert-purple notify_follower post-alert-pos" role="alert">
<p><i class="far fa-bell"></i> <%= notify_follower.user.username %> <%= notify_follower.message %></p>
</div>
<% end %>
post_feed_notifier_relay_job.rb
class PostFeedNotifierRelayJob < ApplicationJob
queue_as :default
def perform(notify_follower)
ActionCable.server.broadcast 'post_channel', message: render_notify_follower(notify_follower)
end
private
def render_notify_follower(notify_follower)
ApplicationController.renderer.render(partial: 'notify_followers/notify_follower', locals: {notify_follower: notify_follower})
end
end
delete_old_notifications_job.rb
class DeleteOldNotificationsJob < ApplicationJob
queue_as :default
def perform(user)
pending_removal_ids = NotifyFollower.order('created_at DESC').limit(1000).pluck(user_id: user.id)
NotifyFollower.where(user_id: pending_removal_ids).where(notification_read: true).destroy_all
end
end
post_channel.rb
class PostChannel < ApplicationCable::Channel
def subscribed
stream_from "post_channel"
end
def unsubscribed
stop_all_streams
end
end
post_follower_notifier.coffee
App.post = App.cable.subscriptions.create "PostChannel",
connected: ->
disconnected: ->
received: (notify_follower) ->
# Called when there's an incoming data on the websocket for this channel
$(".post-notification-location").prepend "<div class='notify_follower'> #{notify_follower.message}</div>"
window.setTimeout (->
$('.alert').fadeTo(500, 0).slideUp 500, ->
$(this).remove()
return
return
), 5000
posts_controller.rb
def index
notify_followers_ids = current_user.following_users.pluck(:id)
@notify_followers = NotifyFollower.where(user_id: notify_followers_ids).order('created_at DESC')
end
javascript ruby-on-rails ruby actioncable
javascript ruby-on-rails ruby actioncable
edited Nov 20 at 21:28
asked Nov 20 at 20:30
Cole Phiper
347
347
add a comment |
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401049%2fhow-to-set-read-attribute-for-broadcast-style-notification-with-actioncable-rail%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53401049%2fhow-to-set-read-attribute-for-broadcast-style-notification-with-actioncable-rail%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown