ruby-on-railsahoymerit-gem

Devise Ahoy track link visits


Hello I have a rails app that is a closed community using devise, ahoy and merit.

We have a scaffold called resources. Each resource has a link

User model

class User < ApplicationRecord
  has_merit
  has_many :visits, class_name: “Ahoy::Visit”
end

Resources model

class Resource < ApplicationRecord
  has_rich_text :description
  belongs_to :category
end

Controller

I want to use Ahoy to track users who click through the link so that I can award points with merit for the visit.

View

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Link</th>
      <th>Category</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @resources.each do |resource| %>
      <tr>
        <td><%= resource.title %></td>
        <td><%= link_to "Learn More", resource.link, class: 'btn btn-dark btn-sm' %></td>
        <td><%= resource.category.name %></td>
        <td><%= link_to 'Show', resource %></td>
        <td><%= link_to 'Edit', edit_resource_path(resource) %></td>
        <td><%= link_to 'Destroy', resource, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

Schema

create_table "resources", force: :cascade do |t|
    t.string "title"
    t.string "link"
    t.bigint "category_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["category_id"], name: "index_resources_on_category_id"
  end

Routes

Rails.application.routes.draw do
  resources :visits
  resources :resources
devise_for :users, controllers: { registrations: 'registrations' }
end

How would I track the link click, and assign points?


Solution

  • lets make a request to visits_controller when a link is clicked. config/routes.rb resources :visits

    controllers/visits.rb

    class VisitsController < ApplicationController
        def create
            Ahoy::Visit.track('click', link_id: params[:resource_id])
        end
    end
    

    I assume ahoy.authenticate(user) is written somewhere Lets add class resource to link and link id as data attr, so that we can bind an ajax call to visits controller carrying necessary data view

    <td><%= link_to "Learn More", resource.link, class: 'resource btn btn-dark btn-sm' data: {resource_id: resource.id} %></td>
    

    assets/javascripts/tracker.js

    (document).on('turbolinks:load', function() { #or whatever you used to do in your app
        $('a.resource').on('click', function() {
             that = this
             $.ajax({
                 url: 'visits',
                 method: 'POST',
                 data: {resource_id: $(that).data('resource_id')}
             })
        })
    })