[Dbix-class] add_columns: source or class?
Christopher H. Laco
claco at chrislaco.com
Mon Jul 3 06:46:03 CEST 2006
It's late. Chances are, I'll make no sense, or just ramble on. Sorry in
advance. This is under -current updated this evening.
I have this schema:
> CREATE TABLE cart (
> id varchar(36) NOT NULL default '',
> shopper varchar(36) NOT NULL default '',
> type tinyint(3) NOT NULL default '0',
> name varchar(50) default NULL,
> description varchar(255) default NULL,
> custom varchar(50) default NULL,
> PRIMARY KEY (id)
> );
and this schema class:
> package Handel::Schema::Cart;
> use strict;
> use warnings;
> use base qw/DBIx::Class/;
>
> __PACKAGE__->load_components(qw/Core/);
> __PACKAGE__->table('cart');
> __PACKAGE__->source_name('Carts');
> __PACKAGE__->add_columns(
> id => {
> data_type => 'varchar',
> size => 36,
> is_nullable => 0,
> },
> shopper => {
> data_type => 'varchar',
> size => 36,
> is_nullable => 0,
> },
> type => {
> data_type => 'tinyint',
> size => 3,
> is_nullable => 0,
> default_value => 0
> },
> name => {
> data_type => 'varchar',
> size => 50,
> is_nullable => 1,
> default_value => undef
> },
> description => {
> data_type => 'varchar',
> size => 255,
> is_nullable => 1,
> default_value => undef
> }
> );
> __PACKAGE__->set_primary_key('id');
> __PACKAGE__->has_many(items => 'Handel::Schema::Cart::Item', {'foreign.cart' => 'self.id'});
>
> 1;
The scenario is, I want to add a column to a schema where the table
exists, but the column isn't defined in the given schema class. (aka,
subclasses customizing the stock schema in Handel).
I was under the impression that when working with columns, if you were
not actually writing in the schema class (which proxys back to source),
that you should always work with $schema->source, and not $schema->class.
This code fails:
> $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG} = 1;
> use Handel::Cart::Schema;
> my $schema = Handel::Cart::Schema->connect;
>
> $schema->source('Carts')->add_column('custom');
> print $schema->source('Carts')->columns, "\n";
>
> print $schema->resultset('Carts')->search({custom => 1});
>
> my $new = $schema->resultset('Carts')->create({
> id => 1, custom => 'foo'
> });
with the error on create. Note, search succeeds, and contains the added
column in line 2:
> idshoppertypenamedescriptioncustom
> SELECT me.id, me.shopper, me.type, me.name, me.description, me.custom FROM cart me WHERE ( custom = ? ): '1'
> DBIx::Class::ResultSet::create(): No such column custom on Handel::Schema::Cart at test.pl line 21
Now, changing the code to use class instead of source make things work:
> $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG} = 1;
> use Handel::Cart::Schema;
> my $schema = Handel::Cart::Schema->connect;
>
> $schema->class('Carts')->add_column('custom');
> print $schema->source('Carts')->columns, "\n";
>
> print $schema->resultset('Carts')->search({custom => 1});
>
> my $new = $schema->resultset('Carts')->create({
> id => 1, custom => 'foo'
> });
but source()->columns is now missing the column:
> idshoppertypenamedescription
> SELECT me.id, me.shopper, me.type, me.name, me.description FROM cart me WHERE ( custom = ? ): '1'
> INSERT INTO cart (custom, id) VALUES (?, ?): 'foo', '1'
And as expected, class()->columns yields the expected columns when
add_columns is called on class() instead:
> idshoppertypenamedescriptioncustom
So, which behavior is correct? I thought using source()->add_column was
the proper way, but clearly, create() isn't aware of the new column even
though search is just dandy with it.
-=Chris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: OpenPGP digital signature
Url : http://lists.rawmode.org/pipermail/dbix-class/attachments/20060703/449e05d3/attachment.pgp
More information about the Dbix-class
mailing list