Search code examples
ruby-on-railsrails-activestorage

Count number of views of a video displayed using active storage


Using active storage I am storing videos in a Lesson model;

class Lesson
   has_one_attached :video
end

displayed with this code;

<div class='feed'>
  <%= render partial: 'lesson', collection: @lessons, cached: true %>
</div>

and the partial is;

<% cache lesson do %>
    <div class="video_size">
       <video controls class='video_size'>
          <source src=<%= rails_blob_path(lesson.video) %> type='video/mp4' />
       </video>
     </div>
<% end -%>

I would like to store a count of how often each video is actually played, i.e the play button in the video is pressed. How do I do this?


Solution

  • For my opinion, if you want to count or store how often each video actually saw, you should custom to track

    ActiveStorage::YourController at 'show' action
    

    Like that:

    # In app/controllers/active_storage/base_controller.rb
    class ActiveStorage::BaseController < ActionController::Base
      before_action :your_implemnt_method!
      include ActiveStorage::SetCurrent
    
      protect_from_forgery with: :exception
      def your_implemnt_method!
         ## check what the video you want to increment.
         # and increment number of seen in model via direct for queue it to backgroud worker
         content.plus_seen
         # do something more.
    
      end
    end
    

    to couter_cache or increment the number of viewers, ...etc

    Another solution is: you want to count the number of times the play button on clicked, just using javascript handle click event, so that send the ajax request to to controller to increment the count.

    enter image description here

    JS code handle play

    const player = new Plyr('#player');
    $('.plyr__control[data-plyr="play"]').click(function() {
      if (!player.source){
    
        Rails.ajax({
          type: "POST",
          url: "/url-to-do-sth",
          data: {your_data: data-to-sent},
          success: function(repsonse){
          },
          error: function(repsonse){
            console.log(repsonse);
          }
        })
      }
    })
    

    And in your controller:

    def handle-sth
      begin
        ## Do sothing
        # and increment number of seen in model via direct for queue it to backgroud worker
        content.plus_seen
    
        render json: {data: data-to-sent}
      rescue
        render :json => { :errors => ["Error with encode or decode."] }, :status => 422
      end
    end