NAME
DBIO::Candy - Sugar syntax for defining DBIO result classes
VERSION
version 0.900000
SYNOPSIS
package MyApp::Schema::Result::Artist;
use DBIO::Candy;
table 'artists';
primary_column id => {
data_type => 'integer',
is_auto_increment => 1,
};
column name => {
data_type => 'varchar',
size => 100,
};
column bio => {
data_type => 'text',
is_nullable => 1,
};
column created_at => {
data_type => 'timestamp',
set_on_create => 1,
};
column updated_at => {
data_type => 'timestamp',
set_on_create => 1,
set_on_update => 1,
};
unique_constraint [qw(name)];
has_many cds => 'MyApp::Schema::Result::CD', 'artist_id';
1;
PostgreSQL-specific example:
package MyApp::Schema::Result::User;
use DBIO::Candy -components => ['InflateColumn::DateTime'];
table 'users';
primary_column id => {
data_type => 'uuid',
retrieve_on_insert => 1,
};
column name => {
data_type => 'varchar',
size => 100,
};
column role => {
data_type => 'enum',
extra => { list => [qw( admin moderator user guest )] },
is_nullable => 1,
};
column metadata => {
data_type => 'jsonb',
default_value => '{}',
serializer_class => 'JSON',
};
column embedding => {
data_type => 'vector',
size => 1536,
};
column tags => {
data_type => 'text[]',
is_nullable => 1,
};
column created_at => {
data_type => 'timestamp',
set_on_create => 1,
};
column updated_at => {
data_type => 'timestamp',
set_on_create => 1,
set_on_update => 1,
};
column deleted_at => {
data_type => 'timestamp',
is_nullable => 1,
};
1;
DESCRIPTION
DBIO::Candy sits between vanilla DBIO::Core and DBIO::Cake. It keeps the familiar method-based API, but imports shorter helper names so result classes read more cleanly.
By default it:
turns on strict and warnings
sets your parent class to DBIO::Core
exports package methods used to define results as simple subroutines
aliases some method names for clarity
cleans the namespace after export via namespace::clean
IMPORT OPTIONS
Candy is a good fit when you want lighter syntax but still prefer explicit column hashrefs over Cake's DDL-style declarations.
-base
use DBIO::Candy -base => 'MyApp::Schema::Result';
Set the parent class. Defaults to DBIO::Core.
-autotable
use DBIO::Candy -autotable => v1;
Automatically generate the table name from the class name. Version v1 pluralizes (Cat becomes cats), 'singular' does not.
-components
use DBIO::Candy -components => ['InflateColumn::DateTime'];
Load components at import time so they can register their own sugar via DBIO::Candy::Exports.
-perl5
use DBIO::Candy -perl5 => v10;
Enable Perl feature flags (equivalent to use feature ':5.10').
-experimental
use DBIO::Candy -experimental => ['signatures'];
Enable experimental features.
IMPORTED SUBROUTINES
The following are exported with the same name and arguments as their __PACKAGE__->method equivalents:
belongs_to
has_many
has_one
inflate_column
many_to_many
might_have
remove_column
remove_columns
resultset_attributes
resultset_class
sequence
source_name
table
IMPORTED ALIASES
Shorter or clearer names for common methods:
column => 'add_columns'
primary_key => 'set_primary_key'
unique_constraint => 'add_unique_constraint'
relationship => 'add_relationship'
TRANSFORMER FUNCTIONS
has_column
has_column foo => (
data_type => 'varchar',
size => 25,
);
Like add_columns but takes a flat list of key/value pairs (Moose-style) and wraps them into a hashref.
primary_column
primary_column id => {
data_type => 'int',
is_auto_increment => 1,
};
Defines a column and adds it to the primary key in a single call.
unique_column
unique_column name => {
data_type => 'varchar',
size => 30,
};
Defines a column and adds a unique constraint on it in a single call.
indices
indices(
name_idx => 'name',
name_email_idx => ['name', 'email'],
);
Declares one or more secondary indexes on the table. Field lists may be a single column name or an arrayref of column names. Equivalent to the DBICx::Indexing component on DBIx::Class. The indexes are picked up by both the SQL::Translator deploy path (via sqlt_deploy_hook) and the native PostgreSQL deploy path (via pg_indexes), so they end up in the generated DDL regardless of which deploy method is in use.
SETTING DEFAULT IMPORT OPTIONS
Create a subclass to avoid repeating import options:
package MyApp::Schema::Candy;
use base 'DBIO::Candy';
sub base { $_[1] || 'MyApp::Schema::Result' }
sub perl_version { 12 }
sub autotable { 1 }
sub experimental { ['signatures'] }
Then in your result classes:
use MyApp::Schema::Candy;
AUTOTABLE VERSIONS
v1
Extracts the part after ::Result::, removes ::, decamelizes, and pluralizes:
MyApp::Schema::Result::Cat -> cats
MyApp::Schema::Result::LonelyPerson -> lonely_people
'singular'
Same as v1 but without pluralization:
MyApp::Schema::Result::Cat -> cat
MyApp::Schema::Result::LonelyPerson -> lonely_person
TIMESTAMP HELPERS
These are proxy methods for DBIO::Timestamp (loaded automatically):
col_created
col_created; # creates 'created_at' column
col_created 'born_at'; # custom column name
col_updated
col_updated; # creates 'updated_at' column
col_updated 'modified_at'; # custom column name
cols_updated_created
cols_updated_created; # creates both at once
The most common pattern -- one line for both timestamp columns.
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.