Skip to content

Commit

Permalink
Optimize queries
Browse files Browse the repository at this point in the history
  • Loading branch information
parterburn committed Sep 4, 2024
1 parent 00fac73 commit cb630be
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 195 deletions.
40 changes: 40 additions & 0 deletions app/controllers/admin/stats_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Admin::StatsController < ApplicationController
def index
@dashboard = AdminStats.new
@users = User.all
@entries = Entry.all

# Preload data for charts
@users_by_week = @dashboard.users_by_week_since(90.days.ago)
@pro_users_by_week = @dashboard.pro_users_by_week_since(90.days.ago)
@entries_by_week = @dashboard.entries_by_week_since(90.days.ago)
@emails_sent_by_month = @dashboard.emails_sent_by_month_since(90.days.ago)
@payments_by_month = @dashboard.payments_by_month(1.year.ago)

# Use counter cache for frequently accessed counts
@all_count = Entry.count
@photos_count = Entry.only_images.count
@ai_entries_count = Entry.with_ai_responses.count

# User statistics
@total_users = @users.count
@pro_users = @users.pro_only
@free_users = @users.free_only
@monthly_users = @users.monthly
@yearly_users = @users.yearly
@forever_users = @users.forever
@payhere_users = @users.payhere_only
@gumroad_users = @users.gumroad_only
@paypal_users = @users.paypal_only
@referral_users = @users.referrals

# Email statistics
@emails_sent_total = @users.sum(:emails_sent)
@emails_received_total = @users.sum(:emails_received)

# Paginate large datasets
@upgrades = @dashboard.upgraded_users_since(90.days.ago).page(params[:upgrades_page]).per(20)
@bounces = @dashboard.bounced_users_since(90.days.ago).page(params[:bounces_page]).per(20)
@free_users_recent = @dashboard.free_users_created_since(90.days.ago).order(:created_at).page(params[:free_users_page]).per(20)
end
end
19 changes: 9 additions & 10 deletions app/models/admin_stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,21 @@ def users_created_since(date)
end

def free_users_created_since(date)
User.free_only.where("created_at >= ?", date)
User.free_only.where('created_at >= ?', date)
end

def upgraded_users_since(date)
pro_users = []
User.pro_only.includes(:payments).order("payments.created_at ASC").each do | user|
first_payment = user.payments.order('payments.date').try(:first).try(:date)
if first_payment.present? && first_payment > date
pro_users << user
end
end
pro_users
User.pro_only
.joins(:payments)
.where('payments.date > ?', date)
.select('users.*, MIN(payments.date) as first_payment_date')
.group('users.id')
.order('first_payment_date ASC')
end

def bounced_users_since(date)
User.where("emails_bounced > 0").where("updated_at >= ?", date)
User.where('emails_bounced > 0')
.where('updated_at >= ?', date)
end

def entries_per_day_for(user)
Expand Down
198 changes: 14 additions & 184 deletions app/views/admin/stats.html.haml
Original file line number Diff line number Diff line change
@@ -1,184 +1,14 @@
- title ("Admin Stats")
= javascript_include_tag "//www.gstatic.com/charts/loader.js", "chartkick"
.row.s-admin-container.container{style: 'margin: 0 auto;'}
.col-md-12
%h3
Admin Stats

.col-md-12
%hr

.col-md-12
.row
.col-md-3
%strong All Entries
- all_count = Entry.all.size
.col-md-2
%strong #{format_number(all_count)}
.row
.col-md-3
%strong All Entries with Photos
- photos_count = Entry.only_images.size
.col-md-2
=link_to admin_photos_path do
%strong #{format_number(photos_count)}
%span{style: "margin-left: 10px;"} #{number_to_percentage(photos_count.to_f/all_count.to_f*100, precision: 0)}
.row
.col-md-3
%strong All Entries using DabbleMeGPT
- ai_entries = Entry.with_ai_responses
.col-md-2
%strong #{format_number(ai_entries.size)}
%span{style: "margin-left: 10px;"} #{format_number(ai_entries.pluck(:user_id).uniq.size)} users
.col-md-12
%hr
.col-md-12
.row
.col-md-3
%strong All
.col-md-2
%strong #{format_number(User.all.size)}
.row
.col-md-3
%strong Pro / Free
.col-md-2
%strong #{format_number(User.pro_only.size)}
%span{style: "margin-left: 10px;"} #{number_to_percentage(User.pro_only.size.to_f/all_count.to_f*100, precision: 1)}
.col-md-2
%strong #{format_number(User.free_only.size)}
.row
.col-md-3
%strong Pro Monthly / Yearly / Forevers
.col-md-2
%strong #{format_number(User.monthly.size)}
.col-md-2
%strong #{format_number(User.yearly.size)}
%span{style: "margin-left: 10px;"} #{number_to_percentage(User.yearly.size.to_f/User.pro_only.size.to_f*100, precision: 1)}
.col-md-2
%strong #{format_number(User.forever.size)}
.row
.col-md-3
%strong Pro Stripe / Gumroad / Paypal
.col-md-2
%strong #{format_number(User.payhere_only.size)}
.col-md-2
%strong #{format_number(User.gumroad_only.size)}
.col-md-2
%strong #{format_number(User.paypal_only.size)}
-# .col-md-12
-# %hr
-# .col-md-12
-# .row
-# .col-md-3
-# %strong Referrals
-# .col-md-2
-# %strong #{format_number(User.referrals.size)}
-# - User.referrals.pluck(:referrer).uniq.each do |ref|
-# .row
-# .col-md-3
-# = ref
-# .col-md-2
-# #{format_number(User.referrals.where(referrer: ref).size)}
-# .col-md-12
-# %hr
-# .col-md-3
-# %strong Total Emails Sent
-# .col-md-3
-# - emails_sent_total = User.sum(:emails_sent)
-# %strong= format_number(emails_sent_total)
-# .clearfix
-# .col-md-3
-# %strong Total Emails Received
-# .col-md-2
-# - emails_received_total = User.sum(:emails_received)
-# %strong= format_number(emails_received_total)
-# %span{style: "margin-left: 10px;"} #{number_to_percentage(emails_received_total.to_f/emails_sent_total.to_f*100, precision: 0)}
-# .col-md-12
-# %hr
-# .col-md-12
-# %h3 Sign ups over the last 90 days
-# = line_chart @dashboard.users_by_week_since(90.days.ago), discrete: true
-# %br
-# .col-md-12
-# %h3 Pro Upgrades over the last 90 days
-# = line_chart @dashboard.pro_users_by_week_since(90.days.ago), discrete: true
-# %br
-# .col-md-12
-# %h3 Entries over the last 90 days
-# = line_chart @dashboard.entries_by_week_since(90.days.ago), discrete: true
-# %br
-# .col-md-12
-# %h3 Emails over the last 90 days
-# = line_chart @dashboard.emails_sent_by_month_since(90.days.ago), discrete: true
-# %br
-# .col-md-12
-# %h3 Payments by month over the last year
-# = column_chart @dashboard.payments_by_month(1.year.ago), discrete: true
-# %br
-# .col-md-12
-# - upgrades = @dashboard.upgraded_users_since(90.days.ago)
-# %h3 #{pluralize(format_number(upgrades.size), "Upgrade")} from the last 90 days
-# %p
-# %table.table.table-striped.table-hover
-# %tr
-# %th Email
-# %th Upgraded
-# %th Paid
-# %th Entries
-# %th Per day
-# - upgrades.each do |user|
-# %tr{:class => @dashboard.paid_status_for(user)}
-# %td= user.email
-# %td= l(user.payments.first.date.to_date, format: :month_day)
-# %td= user.payments.sum(:amount)
-# %td= user.entries.size
-# %td= @dashboard.entries_per_day_for(user)
-# .col-md-12
-# %hr
-# .col-md-12
-# - bounces = @dashboard.bounced_users_since(90.days.ago)
-# %h3 #{pluralize(format_number(bounces.size), "user")} from the last 90 days has had emails bouncing
-# %p
-# %table.table.table-striped.table-hover
-# %tr
-# %th Email
-# %th Bounces
-# - bounces.each do |user|
-# %tr{:class => @dashboard.paid_status_for(user)}
-# %td= user.email
-# %td= user.emails_bounced
-# .col-md-12
-# %hr
-# .col-md-12
-# - free_users = @dashboard.free_users_created_since(90.days.ago).order(:created_at)
-# %h3 #{pluralize(format_number(free_users.size), "Free User")} from the last 90 days
-# %p
-# %table.table.table-striped.table-hover
-# %tr
-# %th Email
-# %th Signed up
-# %th Entries
-# %th Per day
-# - free_users.each do |user|
-# %tr{:class => @dashboard.paid_status_for(user)}
-# %td= user.email
-# %td= l(user.created_at.to_date, format: :month_day)
-# %td= user.entries.size
-# %td= @dashboard.entries_per_day_for(user)
.col-md-12
%hr
.col-md-12
%h3 #{pluralize(format_number(@bounces.total_count), "user")} from the last 90 days has had emails bouncing
= render partial: 'bounces_table', locals: { bounces: @bounces, dashboard: @dashboard }
= paginate @bounces, param_name: 'bounces_page'

.col-md-12
%hr

.col-md-12
%h3 #{pluralize(format_number(@free_users_recent.total_count), "Free User")} from the last 90 days
= render partial: 'free_users_table', locals: { free_users: @free_users_recent, dashboard: @dashboard }
= paginate @free_users_recent, param_name: 'free_users_page'
8 changes: 8 additions & 0 deletions app/views/admin/stats/_bounces_table.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
%table.table.table-striped.table-hover
%tr
%th Email
%th Bounces
- bounces.each do |user|
%tr{:class => dashboard.paid_status_for(user)}
%td= user.email
%td= user.emails_bounced
12 changes: 12 additions & 0 deletions app/views/admin/stats/_free_users_table.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
%table.table.table-striped.table-hover
%tr
%th Email
%th Signed up
%th Entries
%th Per day
- free_users.each do |user|
%tr{:class => dashboard.paid_status_for(user)}
%td= user.email
%td= l(user.created_at.to_date, format: :month_day)
%td= user.entries.size
%td= dashboard.entries_per_day_for(user)
14 changes: 14 additions & 0 deletions app/views/admin/stats/_upgrades_table.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%table.table.table-striped.table-hover
%tr
%th Email
%th Upgraded
%th Paid
%th Entries
%th Per day
- upgrades.each do |user|
%tr{:class => @dashboard.paid_status_for(user)}
%td= user.email
%td= l(user.first_payment_date.to_date, format: :month_day)
%td= user.payments.sum(:amount)
%td= user.entries_count
%td= @dashboard.entries_per_day_for(user)
Loading

0 comments on commit cb630be

Please sign in to comment.