Karl Forner
Karl Forner

Reputation: 4414

How to override the "new"method in DBIx::Class Tables

I have read here http://search.cpan.org/~frew/DBIx-Class-0.08200/lib/DBIx/Class/Manual/Cookbook.pod#Setting_default_values_for_a_row that a way to set default values for columns was to override the new method.

My problem is that my new method is never called.

User.pm

package MyApp::SchemaTest::Result::User;
use strict;
use warnings;
use base qw/DBIx::Class::Core/;

sub new {
    die "new: @_";
}
__PACKAGE__->table("GECKO_USER");
__PACKAGE__->add_columns(
  "user_id",
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
  "first_name",
  { data_type => "varchar2", is_nullable => 0, size => 45 },
  "last_name",
  { data_type => "varchar2", is_nullable => 0, size => 45 } );
__PACKAGE__->set_primary_key("user_id");

1;

test.pl

use Gecko2::SchemaTest;

my $schema = Gecko2::SchemaTest->connect("dbi:SQLite:$FindBin::Bin/../db/gecko2.sqlite");
ok($schema, "got schema");

my $user = $schema->resultset('User')->find( { login => 'toto' });
use DDP;
p $user;

And I get the $user object fully constructed and operational, meaning my brand new method is never called. Why not ???

I have tried to move it around but without any success...

Upvotes: 1

Views: 558

Answers (2)

Karl Forner
Karl Forner

Reputation: 4414

I eventually found the solution: to control the instantiation of row objects from the database/storage, you need to override the inflate_default method.

From the doc:

All DBIx::Class::ResultSet methods that retrieve data from the database and turn it into row objects call this method (*inflate_default*).

Extend this method in your Result classes to hook into this process, for example to rebless the result into a different class.

Of course if you need to control the instantiation of row objects by the new method, you have to override it.

To sum up, if you want to hook on every possible instantiation of row objects, you have to override both inflate_result and new.

Upvotes: 0

Alexander Hartmaier
Alexander Hartmaier

Reputation: 2204

I you call find a Result/Row object is constructed from the values in the database. The case described in the cookbook is for creating new row objects e.g. by calling $rs->create.

Why would you want to override values coming from the database?

Note that you can also set a default value for a column with the 'default_value' attribute. This won't set the column value if you construct a row object with new_result but set the database default column value if you deploy your database with $schema->deploy.

If you want to set the value for a new row object take a look at DBIx::Class::DynamicDefault.

Upvotes: 2

Related Questions