How to set read attribute for broadcast-style notification with ActionCable Rails 5.2












0














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









share|improve this question





























    0














    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









    share|improve this question



























      0












      0








      0







      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









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 21:28

























      asked Nov 20 at 20:30









      Cole Phiper

      347




      347





























          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
          });


          }
          });














          draft saved

          draft discarded


















          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
















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Wiesbaden

          Marschland

          Dieringhausen