title: Update presence table with Action Cable
body: <p>For a Rails 5.2.2 application with <a href="https://github.com/plataformatec/devise" rel="nofollow noreferrer">Devise</a> I implemented the presence example of <a href="https://guides.rubyonrails.org/action_cable_overview.html#example-1-user-appearances" rel="nofollow noreferrer">https://guides.rubyonrails.org/action_cable_overview.html#example-1-user-appearances</a> with the following files:</p>
  
  <p><strong>app/channels/appearance_channel.rb</strong></p>
  
  <pre><code>class AppearanceChannel &lt; ApplicationCable::Channel
    def subscribed
      current_user.appear
    end
  
    def unsubscribed
      current_user.disappear
    end
  
    def appear(data)
      current_user.appear(on: data['appearing_on'])
    end
  
    def away
      current_user.away
    end
  end
  </code></pre>
  
  <p><strong>app/assets/javascripts/cable/subscriptions/appearance.coffee</strong></p>
  
  <pre><code>App.cable.subscriptions.create "AppearanceChannel",
    # Called when the subscription is ready for use on the server.
    connected: -&gt;
      @install()
      @appear()
  
    # Called when the WebSocket connection is closed.
    disconnected: -&gt;
      @uninstall()
  
    # Called when the subscription is rejected by the server.
    rejected: -&gt;
      @uninstall()
  
    appear: -&gt;
      # Calls `AppearanceChannel#appear(data)` on the server.
      @perform("appear", appearing_on: $("main").data("appearing-on"))
  
    away: -&gt;
      # Calls `AppearanceChannel#away` on the server.
      @perform("away")
  
  
    buttonSelector = "[data-behavior~=appear_away]"
  
    install: -&gt;
      $(document).on "turbolinks:load.appearance", =&gt;
        @appear()
  
      $(document).on "click.appearance", buttonSelector, =&gt;
        @away()
        false
  
      $(buttonSelector).show()
  
    uninstall: -&gt;
      $(document).off(".appearance")
      $(buttonSelector).hide()
  </code></pre>
  
  <p>Then I added the following two methods to my <code>users</code> model to update the <code>is_present</code> attribute when ever a user is present or not.</p>
  
  <p><strong>app/models/users.rb</strong></p>
  
  <pre><code>[...]
  def appear
    self.update_attributes(is_present: true)
  end
  
  def disappear
    self.update_attributes(is_present: false)
  end
  [...]
  </code></pre>
  
  <p>On the index page <code>main#index</code> I display a list of all users with their presence status:</p>
  
  <p><strong>app/controllers/main_controller.rb</strong></p>
  
  <pre><code>[...]
  def index
    @users = User.order(:last_name)
  end
  [...]
  </code></pre>
  
  <p><strong>app/views/main/index.html.erb</strong></p>
  
  <pre><code>&lt;h1&gt;Users&lt;/h1&gt;
  
  &lt;%= render partial: "presence_table", locals: {users: @users} %&gt;
  </code></pre>
  
  <p><strong>app/views/main/_presence_table.html.erb</strong></p>
  
  <pre><code>&lt;div class="presence-table"&gt;
    &lt;table class="table table-striped"&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th&gt;&lt;%= User.human_attribute_name("last_name") %&gt;&lt;/th&gt;
          &lt;th&gt;&lt;%= User.human_attribute_name("is_present") %&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;% users.each do |user| %&gt;
          &lt;tr&gt;
            &lt;td&gt;&lt;%= user.last_name %&gt;&lt;/td&gt;
            &lt;td&gt;&lt;%= user.is_present %&gt;&lt;/td&gt;
          &lt;/tr&gt;
        &lt;% end %&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
  </code></pre>
  
  <h2>Question</h2>
  
  <p>How can I auto update the table with Action Cable when ever a presence of a user gets changed? In my understanding it should be possible with the existing parts but I don't know how to do it.</p>
  
  <p>I don't want the user to have to reload the <code>main#index</code> page to get an up to date presence list but to push the content of <code>_presence_table.html.erb</code> when ever a users presence changes.</p>