基于Devise、Ahoy与Merit的Rails应用:追踪链接点击并分配积分
Hey there! Let's break down how to implement link click tracking with Ahoy and reward points via Merit for your Rails closed community app. Here's a step-by-step approach that fits your existing setup:
1. Fix a Small Quotation Mark Issue First
First, notice your User model has a Chinese quotation mark around Ahoy::Visit—this will cause errors. Update it to use English quotes:
class User < ApplicationRecord has_merit has_many :visits, class_name: "Ahoy::Visit" end
2. Add a Tracking Route
We need a middleman action to log the click before redirecting to the external link. Update your routes to add a member action for resources:
Rails.application.routes.draw do resources :visits resources :resources do member do get :track_click # Adds /resources/:id/track_click route end end devise_for :users, controllers: { registrations: 'registrations' } end
3. Implement the Tracking Action in ResourcesController
Add a new action to your ResourcesController that handles the click tracking, points allocation, and redirect:
class ResourcesController < ApplicationController # Ensure only logged-in users can trigger this (fits your closed community) before_action :authenticate_user!, only: [:track_click] # Reuse the existing set_resource method for fetching the resource before_action :set_resource, only: [:track_click, :show, :edit, :update, :destroy] # ... keep your existing controller actions (index, show, etc.) ... def track_click # 1. Log the click event with Ahoy ahoy.track "Resource link clicked", resource_id: @resource.id, link: @resource.link, category_id: @resource.category_id # 2. Award points via Merit (adjust the number to your preference) current_user.add_points(10) # 3. Redirect to the actual external link redirect_to @resource.link, allow_other_host: true end private # Make sure this method exists (scaffold should have generated it) def set_resource @resource = Resource.find(params[:id]) end end
4. Update the View to Use the Tracking Link
Replace your direct external link in the view with the new tracking route:
<td><%= link_to "Learn More", track_click_resource_path(resource), class: 'btn btn-dark btn-sm' %></td>
5. Configure Merit Point Rules
If you haven't already, run rails generate merit:install to create the Merit initializer. Then open config/initializers/merit.rb and add a rule for the click action:
Merit::PointRules.new do # Award 10 points each time a user clicks a resource link rule "Resource link clicked", to: :user, score: 10 end # Optional: Add a badge for frequent resource clickers Merit::Badge.create!( id: 1, name: "Resource Explorer", description: "Clicked on 5+ resource links", level: 1, condition: { num_points: { greater_than_or_equal_to: 50 } } # 5 clicks × 10 points = 50 )
6. Optional: Prevent Point Farming
To stop users from spamming clicks to earn points, add a check in the track_click action to limit how often they can earn points for the same resource:
def track_click # Check if the user clicked this resource in the last 24 hours recent_click = Ahoy::Event.where( user_id: current_user.id, name: "Resource link clicked", properties: { resource_id: @resource.id } ).where("created_at > ?", 24.hours.ago).exists? unless recent_click current_user.add_points(10) ahoy.track "Resource link clicked", resource_id: @resource.id, link: @resource.link end redirect_to @resource.link, allow_other_host: true end
Now when a logged-in user clicks "Learn More", the app will:
- Log the click event in Ahoy's
ahoy_eventstable - Award points to the user via Merit
- Redirect them to the external resource link
内容的提问来源于stack exchange,提问作者Joe Bloggos

