Umami::Models
A Ruby gem that provides read-only ActiveRecord models for accessing Umami Analytics data directly from Rails applications. This gem allows you to query Umami's database directly for analytics data, reports, and user information.
Features
- Read-only ActiveRecord models for all Umami database tables
- Support for PostgreSQL connections
- Built-in query scopes for common analytics queries
- Association mappings between models
Installation
Add this line to your application's Gemfile:
gem 'umami-read-models'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install umami-read-models
Configuration
Setup with Rails Multi-Database Support
This gem is designed to work with Rails 6+ multiple database support. Configure your database in config/database.yml
:
# config/database.yml
production:
primary:
# Your main Rails database configuration
umami:
adapter: postgresql
host: <%= ENV['UMAMI_DB_HOST'] %>
port: <%= ENV['UMAMI_DB_PORT'] || 5432 %>
database: <%= ENV['UMAMI_DB_NAME'] %>
username: <%= ENV['UMAMI_DB_USER'] %>
password: <%= ENV['UMAMI_DB_PASSWORD'] %>
Configure the gem in an initializer (e.g., config/initializers/umami_read_models.rb
):
# For a simple setup with one database
Umami::Models.configure do |config|
config.database = :umami
end
# Or for read replicas
Umami::Models.configure do |config|
config.database = { writing: :umami, reading: :umami_replica }
end
Important: The configuration must be set during application initialization, not in an after_initialize
block.
Note about read replicas: Even though the models are read-only, Rails still requires a :writing
connection to be defined. Both connections can point to the same database if you don't have a read replica.
Usage
Available Models
-
Umami::Models::User
- Umami users -
Umami::Models::Website
- Tracked websites -
Umami::Models::Session
- Visitor sessions -
Umami::Models::WebsiteEvent
- Page views and custom events -
Umami::Models::EventData
- Custom event data -
Umami::Models::SessionData
- Session metadata -
Umami::Models::Team
- Teams -
Umami::Models::TeamUser
- Team memberships -
Umami::Models::Report
- Saved reports
Basic Queries
# Get all websites
websites = Umami::Models::Website.all
# Get active websites for a user
user_websites = Umami::Models::Website
.active
.by_user(user_id)
# Get recent sessions for a website
recent_sessions = Umami::Models::Session
.by_website(website_id)
.recent
.limit(100)
# Get page views for the last 7 days
page_views = Umami::Models::WebsiteEvent
.by_website(website_id)
.page_views
.by_date_range(7.days.ago, Time.current)
Working with Sessions
# Get sessions by browser
chrome_sessions = Umami::Models::Session
.by_website(website_id)
.by_browser('Chrome')
.by_date_range(start_date, end_date)
# Get sessions by country
us_sessions = Umami::Models::Session
.by_website(website_id)
.by_country('US')
# Get session with events
session = Umami::Models::Session.find(session_id)
events = session.website_events.page_views
Working with Events
# Get custom events
custom_events = Umami::Models::WebsiteEvent
.by_website(website_id)
.custom_events
.by_event_name('button_click')
# Get events with UTM parameters
campaign_events = Umami::Models::WebsiteEvent
.by_website(website_id)
.with_utm_campaign('summer_sale')
# Get event data
event = Umami::Models::WebsiteEvent.find(event_id)
event_data = event.event_data
Analytics Queries
# Get unique visitors (sessions) by day
daily_visitors = Umami::Models::Session
.by_website(website_id)
.group("DATE(created_at)")
.count
# Get top pages
top_pages = Umami::Models::WebsiteEvent
.by_website(website_id)
.page_views
.group(:url_path)
.order('count_all DESC')
.limit(10)
.count
# Get referrer domains
referrers = Umami::Models::WebsiteEvent
.by_website(website_id)
.where.not(referrer_domain: nil)
.group(:referrer_domain)
.order('count_all DESC')
.count
# Get browser statistics
browser_stats = Umami::Models::Session
.by_website(website_id)
.group(:browser)
.count
Working with Reports
# Get user reports
user_reports = Umami::Models::Report
.by_user(user_id)
.recent
# Get report with parsed parameters
report = Umami::Models::Report.find(report_id)
params = report.parsed_parameters
Read-Only Protection
All models are read-only. Any attempt to create, update, or delete records will raise an error:
# Creating records will raise an error
website = Umami::Models::Website.new(name: "Test")
website.save # => raises ActiveRecord::ReadOnlyRecord
# Updating records will raise an error
website = Umami::Models::Website.find(id)
website.update(name: "New Name") # => raises ActiveRecord::ReadOnlyRecord
# Deleting records will raise an error
website.destroy # => raises ActiveRecord::ReadOnlyRecord
Advanced Usage
Custom Queries
You can use all ActiveRecord query methods:
# Complex query example
Umami::Models::WebsiteEvent
.joins(:session)
.where(website_id: website_id)
.where(sessions: { country: 'US' })
.where(created_at: 30.days.ago..Time.current)
.group(:url_path)
.having('COUNT(*) > ?', 100)
.pluck(:url_path, 'COUNT(*)')
Raw SQL
For complex analytics queries, you can use raw SQL with proper parameterization:
sql = <<-SQL
SELECT
DATE(created_at) as date,
COUNT(DISTINCT session_id) as visitors,
COUNT(*) as page_views
FROM website_event
WHERE website_id = ?
AND created_at >= ?
GROUP BY DATE(created_at)
ORDER BY date DESC
SQL
results = Umami::Models::Base.connection.exec_query(
sql,
'SQL',
[[nil, website_id], [nil, 30.days.ago]]
)
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
Releasing a New Version
- Update the version number in
lib/umami/models/version.rb
- Update the CHANGELOG.md with the new version and changes
- Commit the changes:
git commit -am "Release version X.Y.Z"
- Create a tag:
git tag vX.Y.Z
- Push the changes and tag:
git push origin main --tags
The GitHub Action will automatically:
- Run the test suite
- Build the gem
- Publish to RubyGems.org
- Create a GitHub release
Note: You need to set up the RUBYGEMS_API_KEY
secret in your GitHub repository settings for automatic publishing to work.
Manual Release
If you need to release manually:
gem build umami-read-models.gemspec
gem push umami-read-models-*.gem
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/azeitler/umami-read-models.