惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
腾讯CDC
博客园 - 聂微东
爱范儿
爱范儿
罗磊的独立博客
P
Proofpoint News Feed
博客园 - Franky
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
Jina AI
Jina AI
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
美团技术团队
MongoDB | Blog
MongoDB | Blog
WordPress大学
WordPress大学
A
About on SuperTechFans
I
InfoQ
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Help Net Security
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
I built rails-persona — behavioral analytics for Rails wi...
Syed Ghani · 2026-06-01 · via DEV Community

Syed Ghani

The problem

Every SaaS app eventually needs to answer the same questions:

  • Which features do my users actually use?
  • Who are my most active users?
  • When did a user last do something meaningful?
  • Which users are going inactive?

The typical answer is "add Mixpanel" or "set up Segment." But that means:

  • Sending your user data to a third party
  • Paying for another service
  • Adding a JS snippet
  • Learning another dashboard

For most Rails apps, this is overkill. The data you need is already in your database.


What I built

rails-persona is a Ruby gem that adds model-level behavioral analytics directly to your ActiveRecord models. No external services, no JS, no cookies — just your own database.

class User < ApplicationRecord
  include Persona::Trackable

  persona do
    track :login
    track :export_report
    track :view_dashboard
    track :upgrade_plan
  end
end

Then track actions anywhere in your app:

current_user.track!(:login)
current_user.track!(:upgrade_plan, metadata: { plan: "pro", amount: 49 })

And query behavior instantly:

user.most_frequent_action       # => :login
user.inactive_since?(30)        # => false
user.persona_summary            # => { login: 42, export_report: 5 }
user.daily_activity(7)          # => { "2024-05-28" => 4, "2024-05-29" => 7 }
user.peak_hour                  # => 14  (2pm)
User.persona_leaderboard        # => top 10 most active users


How it's different from ahoy

ahoy is a great gem but it solves a different problem — it tracks HTTP visits and page views. rails-persona tracks what users do inside your app at the model level.

ahoy rails-persona
Focus HTTP visits + page views Model actions + behavior
Needs JS Yes No
Async built-in No Yes (Sidekiq)
Bulk tracking No Yes (insert_all!)
Class leaderboards No Yes
Works on any model Awkward First-class

Key features

Async tracking — never slow down a request:

Persona.configure do |config|
  config.async = true  # fires a Sidekiq job
end

Bulk tracking — uses insert_all! under the hood:

user.bulk_track!([:login, :view_dashboard, :export_report])

Open tracking — skip the whitelist entirely:

persona do
  open_tracking!  # any string is valid
end

Data pruning — keep your DB clean:

Persona.configure do |config|
  config.max_events_per_record  = 500
  config.auto_prune_after_days  = 90
end

Works on any model — not just User:

class Post < ApplicationRecord
  include Persona::Trackable

  persona do
    track :viewed
    track :shared
    track :bookmarked
  end
end

Post.persona_class_summary  # => { viewed: 50_420, shared: 890 }


Installation

# Gemfile
gem "rails-persona"

bundle install
rails db:migrate


Why I built this

I was the sole engineer on a production SaaS called CinnaLab PRM — an AI-powered Partner Relationship Management platform. I kept wanting to know things like "which users are using the partner portal vs ignoring it?" and "who's about to churn based on inactivity?"

I didn't want to set up Mixpanel for an internal SaaS. I just wanted to query my own database. rails-persona is what I wish had existed.


Links

If you try it, I'd love feedback — open an issue or leave a comment below!