The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Form::Processor::Model::CDBI - model class for Form::Processor based on Class::DBI

SYNOPSIS

    package MyApplication::Form::User;
    use strict;
    use base 'Form::Processor::Model::CDBI';


    # Associate this form with a CDBI class
    sub object_class { 'MyDB::User' }

    # Define the fields that this form will operate on
    sub profile {
        my $self = shift;

        return {
            required => {
                name        => 'Text',
                age         => 'PosInteger',
                sex         => 'Select',
                birthdate   => 'DateTimeDMYHM',
            },
            optional => {
                hobbies     => 'Multiple',
                address     => 'Text',
                city        => 'Text',
                state       => 'Select',
            },

            dependency => [
                [qw/ address city state /],
            ],
        };
    }

DESCRIPTION

This is a Form::Processor::Model add-on module. This module is for use with Class::DBI objects. A form is associated with one of your CDBI table classes (e.g. Artists, Users) and then your forms can be populated with data from the database row, and select options from has_a and many-to-many relationships are also selected automatically.

Your application code calls the update_from_form() method to validate and ( if validation passes) to update or insert the row into the table.

Your form inherits from Form::Processor::Model::CDBI as shown in the SYNOPSIS instead of directly from Form::Processor.

METHODS

object_class

This method is typically overridden in your form class and relates the form to a specific Class::DBI table class. This is the mapping between the form and the columns in the table the form operates on.

The module uses this information to lookup options in related tables for both select and multiple select (many-to-many) relationships.

If not defined will attempt to use the class of $form->item, if set.

Typically, this method is overridden as shown above, and is all you need to do to use this module. This can also be a parameter when creating a form instance.

init_item

This is called first time $form->item is called. It calls basically does:

    return $self->object_class->retrieve( $self->item_id );

But also validates that the item id matches /^\d+$/. Override this method in your form class (or form base class) if your ids do not match that pattern.

guess_field_type

Pass in a column and will try and determine the field type. Currently only looks at CDBI relationships. Would be nice to use the database to determine the types as well.

Must set $self->object_class to return the related item class.

Returns the type in scalar context, returns the type and maybe the related table in list context.

Currently returns:

    DateTimeDMYHM   - for a has_a relationship that isa DateTime
    Select          - for a has_a relationship
    Multiple        - for a has_many

otherwise:

    DateTimeDMYHM   - if the field ends in _time
    Text            - otherwise
lookup_options

Returns a array reference of key/value pairs for the column passed in. Calls $field->label_column to get the column name to use as the label. The default is "name". The labels are sorted by Perl's cmp sort.

If there is an "active" column then only active are included, with the exception being if the form (item) has currently selected the inactive item. This allows existing records that reference inactive items to still have those as valid select options. The inactive labels are formatted with parenthesis to indicate in the select list that they are inactive.

The active column name is determined by calling:

    $active_col = $form->can( 'active_column' )
        ? $form->active_column
        : $class->can( 'active_column' )
            ? $class->active_column
            : $field->active_column;

Which allows setting the name of the active column globally for a given form if your tables are consistently named (all lookup tables have the same column name to indicate they are active), or on a per-field basis.

If the active column is not set on the form then will look for a method on the Class::DBI class also called "active_column". This allows using a method in your Class::DBI base class to define your active column name:

    sub active_column { return 'is_active' }

Finally, if that method is not found then will call the method on the field. This allows overriding the active column name for a specific field. The default method returns the column name "active".

In addition, if the foreign class is the same as the item's class (or the class returned by object_class) then options pointing to item are excluded. The reason for this is for a table column that points to the same table (self referenced), such as a "parent" column. The assumption is that a record cannot be its own parent.

init_value

Populate $field->value with object ids from the CDBI object. If the column expands to more than one object then an array ref is set.

update_from_form
    my $ok = $form->update_from_form( $parameter_hash );

Update or create the object from values in the form.

Any field names that are related to the class by "has_many" and have a mapping table will be updated. Validation is run unless validation has already been run. ($form->clear might need to be called if the $form object stays in memory between requests.)

The update/create is done inside a transaction if the method do_transaction() is available. It's recommended that your CDBI model class supplies that method.

The actual update is done in the update_model method. Your form class can override that method (but don't forget to call SUPER!) if you wish to do additional database inserts or updates. This is useful when a single form updates multiple tables. (If you are doing much of that review your schema design....). If anything goes wrong in the update make sure you die. Assuming you have a standard do_transaction() method this will call a rollback. You should no use do_transaction() in your overridden method unless is supports nested calls or you are not calling SUPER.

Pass in hash reference of parameters.

Returns false if form does not validate. Very likely dies on database errors.

model_validate

Validates profile items that are dependent on the model. Currently, "unique" fields are checked to make sure they are unique.

This validation happens after other form validation. The form already has any field values entered in $field->value at this point.

validate_unique

Checks that the value for the field is not currently in the database.

items_same

Returns true if the two passed in cdbi objects are the same object. Can't trust that the Live_Object index is in use.

If both are undefined returns true. But don't call it that way.

obj_key

returns a key for a given object, or undef if the object is undefined.

AUTHOR

Bill Moseley

LICENSE

This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

Form::Processor