Search code examples
ruby-on-railsahoy

How to use ahoy to track views of posts?


I have multiple posts and I just want to track all the views (including people without accounts) of the posts (so the page itself). I have two methods that I have tried:

1st method

I have added this ahoy.track "Viewed Post", title: @post.id in my controller and <%= Ahoy::Event.joins(:visit).where(name: "Viewed Post").uniq.count("visits.visitor_id") %> to my view.```. The only problem is that it is displaying 0 and not changing.

2nd method

Added visitable to my post model. Ran a migration to add visit id to posts. Also added <%= Post.joins(:visit).distinct.count(:visit_id) %> to my view. The only problem is that the view count is stuck at 1 and it is the same for all the posts.

What am I doing wrong?


Solution

  • I struggled with this for a while aswell. I was able to mostly get it to work.

    Your second method won't do what you want because it is tracking something else. Instead of tracking how many views the post has, it tracks 1 single view. It tracks the view that was used to create the post. It does this by attaching the view to the model.

    Your first method is close to what you want. However all the events you store arent actually storing the visit id in them, as events do not do this by default. You need to add the visit_id yourself, usually into the properties variable of the Event.


    Here is you would need to do:

    First you would place the tracking code in the controller(most likely in the "show" portion):

    if not Ahoy::Event.where(name: "Post:#{@post.id}", properties: current_visit.visit_token).exists?
       ahoy.track "Post:#{@post.id}", current_visit.visit_token
    end
    

    By placing the post id in the name, as well as the text "Post:" it will let it track only views to the Post controller, with the specific id. visit_tokens are unique to a user, and the expire after a given configured time(default 8 hours) so it will only track repeat users if they view the page after the configured time

    Next to read the view count you can place something like this in the controller wherever you want to see views(in show, edit, etc):

    @views = Ahoy::Event.where(name: "Post:#{@post.id}").count
    

    And then in your views you can just use @views


    Note: You aren't supposed to set :properties as a single value, but rather its supposed to hold a hash. However I was not able to figure out how to get it to work.