Build on Rails
Build a dashboard on Rails
Give your team a live read on the business without standing up a BI stack. Avo has first-class dashboards, so metric cards and charts run on the models you already have, inside your Rails app.
250+ paying companies · 2.7M downloads of the avo gem
01 · the hand-built version
What building a dashboard by hand actually costs
A dashboard looks like a weekend project until you need it to stay correct, stay fast, and stay in front of the right people. That is where hand-built dashboards quietly fall apart.
-
01
The numbers live in scattered console queries
Every 'how are we doing this week' turns into someone opening a Rails console, running a query from memory, and pasting the result into Slack. The truth is real, but it is trapped in people's terminals.
-
02
Chartkick is the easy 80 percent
Rendering one chart is quick. The work is the layout, the refresh, the grouping over time, and keeping every card authorized and consistent. That scaffolding is the part you rebuild on every homegrown dashboard.
-
03
A BI tool means shipping your data out
Metabase or Looker connect to a replica, so now you maintain a pipeline and your metrics live in a separate product with its own logins. The definition of 'active customer' drifts between that tool and your app.
-
04
Hand-built cards rot
Cards hardcode queries that slowly fall out of sync as models and columns change. Six months later the dashboard is confidently wrong, and no one is sure which number to trust.
02 · the Avo version
Your models are already the hard part. Avo is the rest.
Avo treats dashboards as a first-class part of the framework, not an afterthought. You define a dashboard class, lay out a grid of cards, and each card runs a query against your real models. Because it lives in your Rails app, a card's definition of a metric is the same code your app already uses, so the numbers stay honest.
Dashboards are a real object, not a one-off view
A dashboard class holds a grid of cards you arrange with grid_cols and dividers. You get a structured, reusable layout instead of a bespoke ERB page. See https://docs.avohq.io/4.0/dashboards.html.
Metric cards for the numbers that matter
A metric card shows a single significant figure, revenue this month, active accounts, open tickets, straight from a query like result Order.paid.sum(:total). One small class per number you care about.
Charts over time without the plumbing
Chartkick cards render trends like signups per week or revenue by plan, with the grouping and rendering handled for you. You supply the query, Avo draws the chart.
Group a dashboard into sections
A divider with a label breaks a busy dashboard into readable groups, so a sales view and an ops view can live on one screen without turning into a wall of cards.
The right dashboard for each team
Build a separate dashboard per audience, finance, support, growth, and use Pundit-style policies to control who sees which. See https://docs.avohq.io/4.0/authorization.html.
Always live, always in your app
Every card queries your production models directly, so there is no export, no sync, and no second definition of a metric to keep aligned. The dashboard reflects the same data your product runs on.
A dashboard laid out with cards, plus one metric card:
class Avo::Dashboards::Sales < Avo::Dashboards::BaseDashboard
self.id = "sales"
self.name = "Sales"
self.grid_cols = 3
def cards
card Avo::Cards::RevenueThisMonth
card Avo::Cards::NewCustomers
card Avo::Cards::OpenDeals
divider label: "Trends"
card Avo::Cards::RevenueOverTime
card Avo::Cards::SignupsByPlan
end
end
class Avo::Cards::RevenueThisMonth < Avo::Cards::MetricCard
self.id = "revenue_this_month"
self.label = "Revenue this month"
def query
result Payment.this_month.sum(:amount)
end
end
03 · the timeline
From first resource to the team running on it
Mount Avo and declare a dashboard with a couple of metric cards over models you already have. You are looking at a real revenue and signups number in the browser, not a console.
Add chart cards for the trends you actually watch and split the board with a divider. The dashboard starts answering 'how are we doing' at a glance.
Put it behind your existing auth, give each team the dashboard that fits them with a policy, and ship it. People check numbers themselves instead of asking an engineer.
The team opens Avo to see how the business is doing. The pasted-into-Slack queries and the drifting spreadsheet retire, and the metrics live next to the data that produces them.
Prefer to prompt?
Hand this to Claude Code, Cursor, or whatever agent you build with, and review what it ships like any other pull request.
Scaffold a brand-new Ruby on Rails app whose numbers a team can read at a glance, with Avo 4 (https://avohq.io) as the management UI and its first-class dashboards (https://docs.avohq.io/4.0/dashboards.html) as the centerpiece. Begin with an empty project and build everything.
1. Run rails new with the default stack, then set up sign-in with bin/rails generate authentication (Rails' built-in authentication generator) and run its migration. Add the avo gem to the Gemfile, bundle, run bin/rails generate avo:install, and mount Avo at /avo so it sits behind the session that generator created.
2. A dashboard only means something when real business data sits behind it, so decide what this app actually runs and model it deliberately. Reason out the handful of entities this domain turns on, the states each one moves through over its life (an enum when a record simply changes status, a table of its own when a transition carries its own data), and how they associate. Lay the schema out before you write a single migration. Concepts likely in play here are the customers or accounts you serve, the orders or payments that produce revenue, the signups that arrive over time, and the open work a team tracks, but treat those as things the design has to account for, not a fixed set of tables to copy.
3. Generate an Avo resource for each model with bin/rails generate avo:resource ModelName (https://docs.avohq.io/4.0/resources.html). On every one, set self.title to the attribute a person recognizes, list the columns worth searching in self.search, and add self.includes for the associations the views load so index pages stay fast. Match each field to its column: text and textarea for strings, number and currency for money, select for enums, belongs_to and has_many for the associations you designed.
4. Turn the things this business does to its records (mark an order paid, close a ticket, activate an account) into Avo Actions generated with bin/rails generate avo:action. Because the app is new, put the real behavior in a model method or a small service object and have the action call into it, so the dashboards read the same state these actions write.
5. Add scopes to the resources for the slices a team narrows by, and Avo filters where someone needs to cut a view in the browser. Then build the dashboards this page is about with bin/rails generate avo:dashboard: set grid_cols, add metric cards that each return result from one query over your models (revenue this month, active accounts, open tickets), add chartkick cards for the trends worth watching grouped by week or month, and break a busy board into readable groups with divider label:. Write each metric as a scope on the model so the card and the rest of the app share one definition of the number.
6. Add Pundit and give each person a role, then build a separate dashboard per audience (sales, support, finance) and gate each one with a policy, so a person opens only the board that fits their job and sees no numbers that are not theirs (https://docs.avohq.io/4.0/authorization.html).
7. Fill db/seeds.rb with believable sample data across every model, spread over the past few months and across the lifecycle states, so each metric card and chart renders a real shape instead of a flat line or a zero.
8. Migrate, seed, boot the server, sign in, and open /avo. Open the sales dashboard and confirm a metric card such as revenue this month shows a live figure computed straight from the seeded records, and that a chart card draws its trend across the seeded weeks.
04 · start today
Stand up a dashboard this week
Avo is per app with unlimited users, so the whole team works from it without the bill scaling with headcount. When you hit an edge Avo doesn't cover, you drop to plain Rails instead of filing a feature request.
More things teams run from their Rails app
Frequently asked questions
- Can I build a dashboard in Ruby on Rails?
- Yes. A dashboard is a set of queries over your data, rendered as numbers and charts, which Rails and Active Record already give you. The tedious part is the layout, refresh, and access control around those queries. Avo provides first-class dashboards so you write the metric and it handles the presentation.
- What is the fastest way to build a metrics dashboard in Rails?
- Define an Avo dashboard and add metric and chart cards that query your existing models. You skip building the grid, the chart rendering, and the authorization by hand, which is where the time goes. A working dashboard over real data is realistic in an afternoon.
- Does Avo work with my existing Rails models?
- Yes. Each card runs a plain query against the Active Record models you already have, so a metric like result User.active.count uses the same code your app uses everywhere else. There is no export step and no separate schema, which is what keeps the numbers trustworthy.
- Can I use charts and write my own queries?
- Yes. Metric cards return a single number from any query you write, and chartkick cards render series like revenue over time or signups by plan. Because the query is ordinary Ruby, you can use your own scopes, joins, and aggregations rather than being limited to a fixed set of widgets.
- Do I need a separate BI tool like Metabase or Looker?
- For most internal dashboards, no. A BI tool connects to a copy of your data and keeps its own metric definitions, which then drift from your app. Avo dashboards run inside your Rails app on live models, so there is no pipeline to maintain and one definition of each metric.
- Can different teams have different dashboards?
- Yes. You can build a separate dashboard per audience, such as sales, support, and finance, and use Pundit-style policies to decide who can open each one. Everyone gets the view that fits their job without seeing numbers that are not theirs to see.