Alba + Typelizer for Inertia Rails Requires: alba , typelizer , alba-inertia gems in Gemfile. Alba serializers for Inertia props with auto-generated TypeScript types. Replaces as_json(only: [...]) with structured, type-safe resources. Before creating a resource, ask: Reusable data shape (user, course)? → Entity resource ( UserResource ) — shared across pages Page-specific props bundle? → Page resource ( UsersIndexResource ) — one per controller action Global data (auth, notifications)? → Shared props resource ( SharedPropsResource ) NEVER: Use as_json when Alba is set up — it bypasses type generation and creates untyped props Skip typelize_from when resource name differs from model — Typelizer can't infer column types and generates unknown Put declare module augmentations in serializers/index.ts — Typelizer-generated types go in serializers/index.ts , manual InertiaConfig goes in globals.d.ts Setup ApplicationResource (all resources inherit from this)
app/resources/application_resource.rb
class ApplicationResource include Alba :: Resource helper Typelizer :: DSL
enables typelize, typelize_from
helper Alba :: Inertia :: Resource
enables inertia: option on attributes
include Rails . application . routes . url_helpers end Controller Integration
app/controllers/inertia_controller.rb
class InertiaController < ApplicationController include Alba :: Inertia :: Controller inertia_share { SharedPropsResource . new ( self ) . to_inertia } end Resource Types Entity Resource (reusable data shape)
app/resources/user_resource.rb
class UserResource < ApplicationResource typelize_from User
needed when resource name doesn't match model
attributes :id , :name , :email typelize :string? attribute :avatar_url do | user | user . avatar . attached ? ? rails_blob_path ( user . avatar , only_path : true ) : nil end end Page Resource (page-specific props)
app/resources/users/index_resource.rb
Naming convention: {Controller}{Action}Resource
class UsersIndexResource < ApplicationResource has_many :users , resource : UserResource typelize :string attribute :search do | obj , _ | obj . params . dig ( :filters , :search ) end end Shared Props Resource Requires Rails Current attributes (e.g., Current.user ) to be configured — see CurrentAttributes .
app/resources/shared_props_resource.rb
class SharedPropsResource < ApplicationResource one :auth , source : proc { Current } attribute :unread_messages_count , inertia : { always : true } do Current . user &. unread_count || 0 end has_many :live_now , resource : LiveSessionsResource , inertia : { once : { expires_in : 5. minutes } } end Convention-Based Rendering With Alba::Inertia::Controller , instance variables auto-serialize: class UsersController < InertiaController def index @users = User . all
auto-serialized via UserResource
@filters
filter_params
plain data passed through
Auto-detects UsersIndexResource
end def show @user = User . find ( params [ :id ] )
Auto-detects UsersShowResource
end end Typelizer + Type Generation typelize_from tells Typelizer which model to infer column types from — needed when resource name doesn't match model. For computed attributes, declare types explicitly: class AuthorResource < ApplicationResource typelize_from User attributes :id , :name , :email typelize :string?
next attribute is string | undefined
attribute :avatar_url do | user | rails_storage_proxy_path ( user . avatar ) if user . avatar . attached ? end typelize filters : "{category: number}"
inline TS type
end Types auto-generate when Rails server runs. Manual: bin/rake typelizer:generate . Inertia Prop Options in Alba The inertia: option on attributes/associations maps to InertiaRails prop types: attribute :stats , inertia : :defer
InertiaRails.defer
has_many :users , inertia : :optional
InertiaRails.optional
has_many :countries , inertia : :once
InertiaRails.once
has_many :items , inertia : { merge : true }
InertiaRails.merge
attribute :csrf , inertia : { always : true }
InertiaRails.always
MANDATORY — READ ENTIRE FILE when using grouped defer, merge with match_on , scroll props, or combining multiple options: references/prop-options.md (~60 lines) — full syntax for all inertia: option variants and inertia_prop alternative syntax. Do NOT load for basic inertia: :defer , inertia: :optional , or inertia: :once — the shorthand above is sufficient. Troubleshooting Symptom Cause Fix TypeScript type is all unknown Missing typelize_from Add typelize_from ModelName when resource name doesn't match model inertia: option has no effect Missing helper Ensure helper Alba::Inertia::Resource is in ApplicationResource Types not regenerating Server not running Typelizer watches files in dev only. Run bin/rake typelizer:generate manually NoMethodError for typelize Missing helper Ensure helper Typelizer::DSL is in ApplicationResource Convention-based rendering picks wrong resource Naming mismatch Resource must be {Controller}{Action}Resource (e.g., UsersIndexResource for UsersController#index ) to_inertia undefined Missing include Controller needs include Alba::Inertia::Controller