ruby
38 lines · 9 steps
Shaping API output with ActiveModel::Serializer in Rails
An ArticleSerializer defines exactly which fields, relations, and computed values an article exposes as JSON.
Explained by
highlit
1class ArticleSerializer < ActiveModel::Serializer
2 attributes :id, :title, :slug, :excerpt, :reading_time, :published_at, :url
3
4 belongs_to :author, serializer: UserSerializer
5 has_many :comments, if: :include_comments?
6 has_many :tags
7
8 meta do
9 { comment_count: object.comments.size }
10 end
11
12 def excerpt
13 object.body.truncate(200, separator: ' ')
14 end
15
16 def reading_time
17 minutes = (object.body.split.size / 200.0).ceil
18 "#{minutes} min read"
19 end
20
21 def published_at
22 object.published_at&.iso8601
23 end
24
25 def url
26 Rails.application.routes.url_helpers.article_url(object)
27 end
28
29 def include_comments?
30 instance_options[:with_comments] || current_user&.admin?
31 end
32
33 private
34
35 def current_user
36 scope
37 end
38end
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1A serializer decouples your JSON shape from your database schema, so the API contract stays stable as models change.
- 2Overriding an attribute method lets you transform or compute values on the fly instead of exposing raw columns.
- 3Conditional associations and scope give you per-request, permission-aware output without branching in the controller.
Related explainers
python
from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, ConfigDict, EmailStr from sqlalchemy.orm import Session
Building a users router in FastAPI
routing
serialization
dependency-injection
Intermediate
7 steps
ruby
class Subscription < ApplicationRecord belongs_to :account enum :status, {
Modeling subscription lifecycle in Rails
enums
scopes
state-management
Intermediate
8 steps
python
import json from dataclasses import dataclass, field, asdict from datetime import datetime from typing import Any
JSON round-tripping with Python dataclasses
dataclasses
serialization
json
Intermediate
6 steps
ruby
class InactiveAccountCleanup BATCH_SIZE = 500 INACTIVITY_THRESHOLD = 18.months
Batch-processing dormant users in Rails
batch-processing
activerecord
service-object
Intermediate
9 steps
rust
use std::fs::File; use std::io::{self, BufWriter}; use std::path::Path;
Serializing config to JSON in Rust
serialization
serde
file-io
Intermediate
7 steps
ruby
def collatz_lengths Enumerator.new do |y| n = 1 loop do
Building infinite sequences with lazy enumerators
lazy-evaluation
enumerators
infinite-sequences
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/shaping-api-output-with-activemodel-serializer-in-rails-explained-ruby-eb3d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.