NAME
DBIx::Class::FormTools - Helper module for building forms with multiple related DBIx::Class objects.
VERSION
This document describes DBIx::Class::FormTools version 0.0.11
SYNOPSIS
This is BETA software
There may be bugs. The interface might change (But the it hasn't changed in a long time, so it is probably safe to use).
Prerequisites
In the examples I use 3 objects, a Film
, an Actor
and a Role
. Role
is a many to many relation between Film
and Actor
.
package MySchema;
use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes(qw[
Film
Actor
Role
]);
package MySchema::Film;
__PACKAGE__->table('films');
__PACKAGE__->add_columns(qw[
id
title
]);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->has_many(roles => 'MySchema::Role', 'film_id');
package MySchema::Actor;
__PACKAGE__->table('films');
__PACKAGE__->add_columns(qw[
id
name
]);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->has_many(roles => 'MySchema::Role', 'actor_id');
package MySchema::Role;
__PACKAGE__->table('roles');
__PACKAGE__->add_columns(qw[
film_id
actor_id
]);
__PACKAGE__->set_primary_key(qw[
film_id
actor_id
]);
__PACKAGE__->belongs_to(film_id => 'MySchema::Film');
__PACKAGE__->belongs_to(actor_id => 'MySchema::Actor');
In your Controller
use DBIx::Class::FormTools;
my $formtool = DBIx::Class::FormTools->new({ schema => $schema });
In your view - HTML::Mason example
<%init>
my $film = $schema->resultset('Film')->find(42);
my $actor = $schema->resultset('Actor')->find(24);
my $role = $schema->resultset('Role')->new;
</%init>
<form>
<input
name="<% $formtool->fieldname($film, 'title', 'o1') %>"
type="text"
value="<% $film->title %>"
/>
<input
name="<% $formtool->fieldname($film, 'length', 'o1') %>"
type="text"
value="<% $film->length %>"
/>
<input
name="<% $formtool->fieldname($film, 'comment', 'o1') %>"
type="text"
value="<% $film->comment %>"
/>
<input
name="<% $formtool->fieldname($actor, 'name', 'o2') %>"
type="text"
value="<% $actor->name %>"
/>
<input
name="<% $formtool->fieldname($role, undef, 'o3', {
film_id => 'o1',
actor_id => 'o2'
}) %>"
type="hidden"
value="dummy"
/>
</form>
In your controller (or cool helper module, used in your controller)
my @objects = $formtool->formdata_to_objects(\%querystring);
foreach my $object ( @objects ) {
# Assert and Manupulate $object as you like
$object->insert_or_update;
}
DESCRIPTION
Introduction
DBIx::Class::FormTools is a data serializer, that can convert HTML formdata to DBIx::Class objects based on element names created with DBIx::Class::FormTools.
It uses user supplied object ids to connect the objects with each-other. The objects do not need to exist on beforehand.
The module is not ment to be used directly, although it can of-course be done as seen in the above example, but rather used as a utility module in a Catalyst helper module or other equivalent framework.
Connecting the dots - The problem at hand
Creating a form with data from one object and storing it in a database is easy, and several modules that does this quite well already exists on CPAN.
What I am trying to accomplish here, is to allow multiple objects to be created and updated in the same form - This includes the relations between the objects i.e. "connecting the dots".
Non-existent ids - Enter object_id
When converting the formdata to objects, we need "something" to identify the objects by, and sometimes we also need this "something" to point to another object in the formdata to signify a relation. For this purpose we have the object_id
which is user definable and can be whatever you like.
METHODS
new
Arguments: { schema => $schema }
Creates new form helper
my $formtool = DBIx::Class::FormTools->new({ schema => $schema });
schema
Arguments: None
Returns the schema
my $schema = $formtool->schema;
fieldname
Arguments: $object, $accessor, $object_id, $foreign_object_ids
my $name_film = $formtool->fieldname($film, 'title', 'o1');
my $name_actor = $formtool->fieldname($actor, 'name', 'o2');
my $name_role = $formtool->fieldname($role, undef,'o3',
{ film_id => 'o1', actor_id => 'o2' }
);
my $name_role = $formtool->fieldname($role,'charater','o3',
{ film_id => 'o1', actor_id => 'o2' }
);
Creates a unique form field name for use in an HTML form.
$object
-
The object you wish to create a key for.
$accessor
-
The attribute in the object you wish to create a key for.
$object_id
-
A unique string identifying a specific object in the form.
$foreign_object_ids
-
A
HASHREF
containingattribute => object_id
pairs, use this to connect objects with each-other as seen in the above example.
formdata_to_object_hash
Arguments: \%formdata
my @objects = $formtool->formdata_to_objects($formdata);
Turn formdata(a querystring) in the form of a HASHREF
into an HASHREF
of DBIx::Class
objects indexed by object_id.
formdata_to_objects
Arguments: \%formdata
my @objects = $formtool->formdata_to_objects($formdata);
Turn formdata(a querystring) in the form of a HASHREF
into an ARRAY
of DBIx::Class
objects.
meta
This is a method which provides access to the current class's metaclass.
CAVEATS
Transactions
When using this module it is prudent that you use a database that supports transactions.
The reason why this is important, is that when calling formdata_to_objects
, DBIx::Class::Row->create()
is called foreach nonexistent object in order to get the primary key
filled in. This call to create
results in a SQL insert
statement, and might leave you with one object successfully put into the database and one that generates an error - Transactions will allow you to examine the ARRAY
of objects returned from formdata_to_objects
before actually storing them in the database.
Automatic Primary Key generation
You must use DBIx::Class::PK::Auto
, otherwise the formdata_to_objects
will fail when creating new objects, as it is unable to determine the value for the primary key, and therefore is unable to connect the object to any related objects in the form.
BUGS AND LIMITATIONS
No bugs have been reported.
Please report any bugs or feature requests to bug-dbix-class-formtools@rt.cpan.org
, or through the web interface at http://rt.cpan.org.
AUTHOR
David Jack Olrik <djo@cpan.org>
LICENCE AND COPYRIGHT
Copyright (c) 2006, David Jack Olrik <djo@cpan.org>
. All rights reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.
TODO
Add form object, that keeps track of object ids automagickly.
Add field generator, that can generate HTML/XHTML fields based on the objects in the form object.