Base
Base class for representations.
Defines how an ActiveRecord model is represented in the API. Drives contracts and runtime behavior. Sensible defaults are auto-detected from database columns but can be overridden. Supports STI and polymorphic associations.
Example: Basic representation
class InvoiceRepresentation < Apiwork::Representation::Base
attribute :id
attribute :title
attribute :status, filterable: true, sortable: true
belongs_to :customer
has_many :items
endExample: Contract
class InvoiceContract < Apiwork::Contract::Base
representation InvoiceRepresentation
endClass Methods
.abstract!
.abstract!
Marks this representation as abstract.
Abstract representations don't require a model and serve as base classes for other representations. Use this when creating application-wide base representations. Subclasses automatically become non-abstract.
Returns
void
Example: Application base representation
class ApplicationRepresentation < Apiwork::Representation::Base
abstract!
end.abstract?
.abstract?
Whether this representation is abstract.
Returns
Boolean
.adapter
.adapter(&block)
Configures adapter options for this representation.
Overrides API-level options. Subclasses inherit parent adapter options.
Returns
void
Yields Configuration
Example
adapter do
pagination do
strategy :cursor
default_size 50
end
end.associations
.associations
The associations for this representation.
Returns
Hash{Symbol => Association}
.attribute
.attribute(name, decode: nil, deprecated: false, description: nil, empty: nil, encode: nil, enum: nil, example: nil, filterable: false, format: nil, max: nil, min: nil, nullable: nil, optional: nil, preload: nil, sortable: false, type: nil, writable: false, &block)
Defines an attribute for this representation.
Subclasses inherit parent attributes.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name | Symbol | The attribute name. | |
decode | Proc, nil | nil | Transform for request input (API to database). Must preserve the attribute type. |
deprecated | Boolean | false | Whether deprecated. Metadata included in exports. |
description | String, nil | nil | The description. Metadata included in exports. |
empty | Boolean, nil | nil | Whether to use empty string instead of null. Serializes nil as "" and deserializes "" as nil. Only valid for :string type. |
encode | Proc, nil | nil | Transform for response output (database to API). Must preserve the attribute type. |
enum | Array, nil | nil | The allowed values. If nil, auto-detected from Rails enum definition. |
example | Object, nil | nil | The example. Metadata included in exports. |
filterable | Boolean | false | Whether the attribute is filterable. |
format | Symbol<:date, :datetime, :double, :email, :float, :hostname, :int32, :int64, :ipv4, :ipv6, :password, :url, :uuid>, nil | nil | Format hint for exports. Does not change the type, but exports may add validation or documentation based on it. Valid formats by type: :decimal/:number (:double, :float), :integer (:int32, :int64), :string (:date, :datetime, :email, :hostname, :ipv4, :ipv6, :password, :url, :uuid). |
max | Integer, nil | nil | The maximum. For :array: size. For :decimal, :integer, :number: value. For :string: length. |
min | Integer, nil | nil | The minimum. For :array: size. For :decimal, :integer, :number: value. For :string: length. |
nullable | Boolean, nil | nil | Whether the value can be null. If nil and name maps to a database column, auto-detected from column NULL constraint. |
optional | Boolean, nil | nil | Whether the attribute is optional for writes. If nil and name maps to a database column, auto-detected from column default or NULL constraint. |
preload | Symbol, Array, Hash, nil | nil | Associations to preload for this attribute. Use when custom attributes depend on associations. |
sortable | Boolean | false | Whether the attribute is sortable. |
type | Symbol<:array, :binary, :boolean, :date, :datetime, :decimal, :integer, :number, :object, :string, :time, :unknown, :uuid>, nil | nil | The type. If nil and name maps to a database column, auto-detected from column type. Defaults to :unknown for json/jsonb columns and when no column exists (custom attributes). Use an explicit type or block in those cases. |
writable | Boolean, Symbol<:create, :update> | false | The write access. true for both create and update, :create for create only, :update for update only. |
Returns
void
Yields Representation::Element
Example: Basic
attribute :title
attribute :price, type: :decimal, min: 0
attribute :status, filterable: true, sortable: trueExample: Custom attribute with preload
attribute :total, type: :decimal, preload: :items
def total
record.items.sum(:amount)
endExample: Nested preload
attribute :total_with_tax, type: :decimal, preload: { items: :tax_rate }
def total_with_tax
record.items.sum { |item| item.amount * (1 + item.tax_rate.rate) }
endExample: Inline type for JSON column
attribute :settings do
object do
string :theme
boolean :notifications
end
endExample: Encode/decode transforms
attribute :status, encode: ->(value) { value.upcase }, decode: ->(value) { value.downcase }Example: Writable only on create
attribute :slug, writable: :createExample: Explicit enum values
attribute :priority, enum: [:low, :medium, :high]Example: Multiple preloads
attribute :summary, type: :string, preload: [:items, :customer]
def summary
"#{record.customer.name}: #{record.items.count} items"
end.attributes
.attributes
The attributes for this representation.
Returns
Hash{Symbol => Attribute}
.belongs_to
.belongs_to(name, deprecated: false, description: nil, example: nil, filterable: false, include: :optional, nullable: nil, polymorphic: nil, representation: nil, sortable: false, writable: false)
Defines a belongs_to association for this representation.
Subclasses inherit parent associations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name | Symbol | The association name. | |
deprecated | Boolean | false | Whether deprecated. Metadata included in exports. |
description | String, nil | nil | The description. Metadata included in exports. |
example | Object, nil | nil | The example. Metadata included in exports. |
filterable | Boolean | false | Whether the association is filterable. |
include | Symbol<:always, :optional> | :optional | The inclusion mode. |
nullable | Boolean, nil | nil | Whether the association can be null. If nil, auto-detected from foreign key column NULL constraint. |
polymorphic | Array<Class<Representation::Base>>, nil | nil | The allowed representation classes for polymorphic associations. |
representation | Class<Representation::Base>, nil | nil | The representation class. If nil, inferred from the associated model in the same namespace (e.g., CustomerRepresentation for Customer). |
sortable | Boolean | false | Whether the association is sortable. |
writable | Boolean, Symbol<:create, :update> | false | The write access. true for both create and update, :create for create only, :update for update only. Requires accepts_nested_attributes_for on the model, where allow_destroy: true also enables deletion. |
Returns
void
See also
Example: Basic
belongs_to :customerExample: Explicit representation
belongs_to :author, representation: AuthorRepresentationExample: Always included
belongs_to :customer, include: :alwaysExample: Polymorphic
belongs_to :commentable, polymorphic: [PostRepresentation, CustomerRepresentation]Example: Custom association
belongs_to :customer
def customer
record.customer || Customer.default
end.deprecated!
.deprecated!
Marks this representation as deprecated.
Metadata included in exports.
Returns
void
Example
deprecated!.deprecated?
.deprecated?
Whether this representation is deprecated.
Returns
Boolean
.description
.description(value = nil)
The description for this representation.
Metadata included in exports.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
value | String, nil | nil | The description. |
Returns
String, nil
Example
description 'A customer invoice'.deserialize
.deserialize(payload)
Transforms a hash or an array of hashes for records.
Applies attribute decoders, maps STI and polymorphic type names, and recursively deserializes nested associations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
payload | Hash, Array<Hash> | The payload to deserialize. |
Returns
Hash, Array<Hash>
Example
InvoiceRepresentation.deserialize(params[:invoice]).example
.example(value = nil)
The example value for this representation.
Metadata included in exports.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
value | Hash, nil | nil | The example. |
Returns
Hash, nil
Example
example id: 1, total: 99.00, status: 'paid'.has_many
.has_many(name, deprecated: false, description: nil, example: nil, filterable: false, include: :optional, representation: nil, sortable: false, writable: false)
Defines a has_many association for this representation.
Subclasses inherit parent associations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name | Symbol | The association name. | |
deprecated | Boolean | false | Whether deprecated. Metadata included in exports. |
description | String, nil | nil | The description. Metadata included in exports. |
example | Object, nil | nil | The example. Metadata included in exports. |
filterable | Boolean | false | Whether the association is filterable. |
include | Symbol<:always, :optional> | :optional | The inclusion mode. |
representation | Class<Representation::Base>, nil | nil | The representation class. If nil, inferred from the associated model in the same namespace (e.g., CustomerRepresentation for Customer). |
sortable | Boolean | false | Whether the association is sortable. |
writable | Boolean, Symbol<:create, :update> | false | The write access. true for both create and update, :create for create only, :update for update only. Requires accepts_nested_attributes_for on the model, where allow_destroy: true also enables deletion. |
Returns
void
See also
Example: Basic
has_many :itemsExample: Explicit representation
has_many :comments, representation: CommentRepresentationExample: Always included
has_many :items, include: :alwaysExample: Custom association
has_many :items
def items
record.items.limit(5)
end.has_one
.has_one(name, deprecated: false, description: nil, example: nil, filterable: false, include: :optional, nullable: nil, representation: nil, sortable: false, writable: false)
Defines a has_one association for this representation.
Subclasses inherit parent associations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name | Symbol | The association name. | |
deprecated | Boolean | false | Whether deprecated. Metadata included in exports. |
description | String, nil | nil | The description. Metadata included in exports. |
example | Object, nil | nil | The example. Metadata included in exports. |
filterable | Boolean | false | Whether the association is filterable. |
include | Symbol<:always, :optional> | :optional | The inclusion mode. |
nullable | Boolean, nil | nil | Whether the association can be null. |
representation | Class<Representation::Base>, nil | nil | The representation class. If nil, inferred from the associated model in the same namespace (e.g., CustomerRepresentation for Customer). |
sortable | Boolean | false | Whether the association is sortable. |
writable | Boolean, Symbol<:create, :update> | false | The write access. true for both create and update, :create for create only, :update for update only. Requires accepts_nested_attributes_for on the model, where allow_destroy: true also enables deletion. |
Returns
void
Example: Basic
has_one :profileExample: Explicit representation
has_one :author, representation: AuthorRepresentationExample: Always included
has_one :customer, include: :alwaysExample: Custom association
has_one :profile
def profile
record.profile || record.build_profile
end.inheritance
.inheritance
The inheritance configuration for this representation.
Auto-configured when the model uses STI and representation classes mirror the model hierarchy. Subclasses share the parent's inheritance configuration.
Returns
Representation::Inheritance, nil
.model
.model(value)
Configures the model class for this representation.
Auto-detected from representation name when not set. Use .model_class to retrieve.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
value | Class<ActiveRecord::Base> | The model class. |
Returns
void
Example
model Invoice.model_class
.model_class
The model class for this representation.
Auto-detected from representation name or set via .model.
Returns
Class<ActiveRecord::Base>
.polymorphic_name
.polymorphic_name
The polymorphic name for this representation.
Uses .type_name if set, otherwise the model's polymorphic_name.
Returns
String
.root
.root(singular, plural = singular.to_s.pluralize)
Configures the JSON root key for this representation.
Auto-detected from model name when not set. Use .root_key to retrieve.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
singular | String, Symbol | The singular root key. | |
plural | String, Symbol | singular.pluralize | The plural root key. |
Returns
void
Example
root :bill, :bills.root_key
.root_key
The root key for this representation.
Derived from model name when .root is not set.
Returns
.serialize
.serialize(resource, context: {}, include: nil)
Transforms a record or an array of records to hashes.
Applies attribute encoders, maps STI and polymorphic type names, and recursively serializes nested associations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
resource | ActiveRecord::Base, Array<ActiveRecord::Base> | The resource to serialize. | |
context | Hash | {} | The serialization context. |
include | Symbol, Array, Hash, nil | nil | The associations to include. |
Returns
Hash, Array<Hash>
Example: Basic
InvoiceRepresentation.serialize(invoice)
# => { id: 1, total: 99.00, status: 'paid' }Example: Collection
InvoiceRepresentation.serialize(invoices)
# => [{ id: 1, ... }, { id: 2, ... }]Example: With associations
InvoiceRepresentation.serialize(invoice, include: [:customer, :items])
# => { id: 1, ..., customer: { id: 1, name: 'Acme' }, items: [...] }Example: Nested associations
InvoiceRepresentation.serialize(invoice, include: { customer: [:address] })
# => { id: 1, ..., customer: { id: 1, name: 'Acme', address: { ... } } }.sti_name
.sti_name
The STI name for this representation.
Uses .type_name if set, otherwise the model's sti_name.
Returns
String
.subclass?
.subclass?
Whether this representation is an STI subclass.
Returns
Boolean
.type_name
.type_name(value = nil)
The type name for this representation.
Overrides the model's default for STI and polymorphic types.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
value | String, Symbol, nil | nil | The type name. |
Returns
String, nil
See also
Example
type_name :personInstance Methods
#context
#context
The serialization context.
Passed from controller or directly to .serialize. Use for data that isn't on the record, like current user or permissions.
Returns
Hash
Example: Override in controller
def context
{ current_user: current_user }
endExample: Access in custom attribute
attribute :editable, type: :boolean
def editable
context[:current_user]&.admin?
end