On May 7, 2007, at 1:16 PM, Christopher H. Laco wrote:
and while it is all working now (thanks Claco!) I have to admit I
still find the behavior counter-intuitive at best. I guess when I
was just inflating DateTime objects it made more sense, since the
inflated values were so much more complex than the representation
that was stored in the database, but when I started using
DBIx::Class::InflateColumn::Currency, it seemed odd to me that
'$10.00' would be inflated to a Data::Currency object if it came
from=
the database, but not if it came from the user. I've fixed this
for
my immediate need by writing an HTML::FormFu::Inflator subclass
that
parallels DBIx::Class::InflateColumn::Currency, but going
forward I'd=
like to avoid repeating so much code, so I've come up with an
idea to=
extend DBIx::Class::InflateColumn to allow user-provided values
to be=
inflated the same way that database values are.
Well, if you call $obj->inflated_field('$10.00');
then do $obj->inflated_field; the second call will return the
inflated=
object.
I'm not sure I see what the problem you're trying to solve is?
[mst]
Well, if you call $obj->inflated_field('$10.00');
The problem is, that will never work. I could be wrong, but
whatever you
pass to inflated columns has to either be an inflated object, or a
valid
value matching EXACTLY what the current DB supports.
In this case '$10.00' is neither a currency object, nor a valid value
for a db column of type float.
The same has always been true for DateTime fields (at least in my
experience):
$obj->col('1-2-2007')
will never work in database that don't grok that datetime format.
But if
you pass in a DateTime object, all is well...
The problem is that it does sometimes work, and I think I've finally
figured out why...
If you set the value with $obj->col( '$10.00' ), and then request the
value with $obj->col, you do indeed get back an inflated value.
Looking through the code however, it appears that the inflation is
done by DBIx::Column::InflateColumn::get_inflated_column, meaning the
value is inflated when you retrieve it, not when you set it.
What this means is that this will work as expected:
$obj->col( '$10.00' );
print ref( $obj->col )."\n"; # will print Data::Currency
However, this will _not_ work as expected:
$obj->col( '$10.00' );
$obj->update;
The reason the second one doesn't work has to do with the inner
workings of get_inflated_column and set_inflated_column.
When you do this: $obj->get_inflated_column( $col );
The get_inflated_column method will look for a previously inflated
value in $self->{ _inflated_column }{ $col } and return it if it
finds it, if it doesn't already have an inflated value, it will call
get_column to retrieve the value from the database, inflate that,
store it in $self->{ _inflated_column }{ $col } and return the
inflated value.
When you do this: $obj->set_inflated_column( $col, Data::Currency->new
( 10, 'USD' ) );
The set_inflated_column method will deflate the object and call
set_column with that value, so that other things that don't
understand the inflated values will work correctly (things like
DBIx::Class::Row::update for example).
When you do this: $obj->set_inflated_column( $col, '$10.00' ); is
where things start to fall apart...
set_inflated_column will call _deflated_column with an argument of
'$10.00', which gets returned unchanged because it isn't a reference,
then it calls set_column with that value, thereby populating the
object with invalid data. Now when you call $obj->update, update
will call get_dirty_columns and pass the results to
SQL::Abstract::update, but since the value was not inflated before it
was deflated, the unchanged value is passed to the database and the
update proceeds with invalid data.
I've been trying to determine the best way to fix this, but writing
tests for it has proven difficult, I think I'm going to have to write
a test class to inflate objects to...
--
Jason Kohles
[EMAIL PROTECTED]
http://www.jasonkohles.com/
"A witty saying proves nothing." -- Voltaire
_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
Searchable Archive: http://www.mail-archive.com/[email protected]/