关于 alba-inertia
这项技能介绍如何在 Inertia Rails 中使用 Alba 序列化器和 Typelizer。它帮助开发者将 Inertia props 组织为可复用资源,并据此生成 TypeScript 类型。
主要功能
- 01定义实体、页面和共享 props 资源
- 02使用 Alba 序列化 Inertia props
- 03通过 Typelizer 生成 TypeScript 类型
- 04支持 defer、optional 等 Inertia prop 选项
- 05提供基于约定的控制器渲染
适用场景
- 01用结构化资源替代无类型的 as_json props
- 02在多个页面复用实体数据结构
- 03为序列化后的 props 生成 TypeScript 类型
- 04为延迟或可选数据设置 Inertia prop 行为
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ inertia-rails/ skills --skill alba-inertia安装后在 Claude Code 中输入/alba-inertia确认已加载。
附带文件references/prop-options.md
详细介绍
Alba + Typelizer 用于 Inertia Rails
要求:Gemfile 中包含 alba、typelizer、alba-inertia gems。
用于 Inertia props 的 Alba 序列化器,可自动生成 TypeScript 类型。
用结构化、类型安全的资源替代 as_json(only: [...])。
创建资源前,请先确认:
- 可复用的数据结构(用户、课程)? → 实体资源(
UserResource)——可在多个页面间共享 - 页面专属的 props 集合? → 页面资源(
UsersIndexResource)——每个控制器操作对应一个 - 全局数据(身份验证、通知)? → 共享 props 资源(
SharedPropsResource)
绝对不要:
- 在已设置 Alba 时使用
as_json——这会绕过类型生成,并创建无类型的 props - 当资源名称与模型不同时省略
typelize_from——Typelizer 无法推断列类型,并会生成unknown - 将
declare module扩展放在serializers/index.ts中——Typelizer 生成的类型应放在serializers/index.ts中,手动编写的 InertiaConfig 应放在globals.d.ts中
设置
ApplicationResource(所有资源均继承自此类)
# 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
控制器集成
# app/controllers/inertia_controller.rb
class InertiaController < ApplicationController
include Alba::Inertia::Controller
inertia_share { SharedPropsResource.new(self).to_inertia }
end
资源类型
实体资源(可复用的数据结构)
# 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
页面资源(页面专属 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
共享 props 资源
需要配置 Rails Current 属性(例如 Current.user)——
请参阅 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
基于约定的渲染
使用 Alba::Inertia::Controller 时,实例变量会自动序列化:
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 + 类型生成
typelize_from 用于告知 Typelizer 应从哪个模型推断列类型——当资源名称
与模型名称不同时需要使用。对于计算属性,请显式声明类型:
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
Rails 服务器运行时会自动生成类型。手动生成:bin/rake typelizer:generate。
Alba 中的 Inertia Prop 选项
属性/关联上的 inertia: 选项会映射到 InertiaRails prop 类型:
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
必须——使用分组 defer、带 match_on 的 merge、滚动 props 或组合多个选项时,请阅读整个文件:
references/prop-options.md(约 60 行)——包含所有 inertia: 选项变体及 inertia_prop 备用语法的完整语法说明。
基本的 inertia: :defer、inertia: :optional 或
inertia: :once 无需加载——以上简写已足够。
故障排除
| 症状 | 原因 | 修复方法 |
|---|---|---|
TypeScript 类型全部为 unknown | 缺少 typelize_from | 资源名称与模型名称不同时,添加 typelize_from ModelName |
inertia: 选项不起作用 | 缺少 helper | 确认 ApplicationResource 中包含 helper Alba::Inertia::Resource |
| 类型未重新生成 | 服务器未运行 | Typelizer 仅在开发环境中监视文件。手动运行 bin/rake typelizer:generate |
typelize 出现 NoMethodError | 缺少 helper | 确认 ApplicationResource 中包含 helper Typelizer::DSL |
| 基于约定的渲染选错资源 | 命名不匹配 | 资源名称必须为 {Controller}{Action}Resource(例如,UsersController#index 对应 UsersIndexResource) |
to_inertia 未定义 | 缺少 include | 控制器需要 include Alba::Inertia::Controller |
相关技能
- Prop 类型 →
inertia-rails-controllers(defer、once、merge、scroll) - TypeScript 配置 →
inertia-rails-typescript(globals.d.ts中的 InertiaConfig)