sub has_many {
my ($class, $rel, $f_class, $f_key, $args) = @_;
- my $self_key;
+ my @f_method;
if (ref $f_class eq 'ARRAY') {
- ($f_class, $self_key) = @$f_class;
+ ($f_class, @f_method) = @$f_class;
}
- if (!$self_key || $self_key eq 'id') {
- my ($pri, $too_many) = keys %{ $class->_primaries };
- $class->throw( "has_many only works with a single primary key; ${class} has more" )
+ my ($pri, $too_many) = keys %{ $class->_primaries };
+ $class->throw( "has_many only works with a single primary key; ${class} has more" )
if $too_many;
- $self_key = $pri;
- }
+ my $self_key = $pri;
eval "require $f_class";
unless $f_class->_columns->{$f_key};
$args ||= {};
my $cascade = not (ref $args eq 'HASH' && delete $args->{no_cascade_delete});
- $class->add_relationship($rel, $f_class,
+
+ $class->add_relationship($rel, $f_class,
{ "foreign.${f_key}" => "self.${self_key}" },
{ accessor => 'multi',
join_type => 'LEFT',
($cascade ? ('cascade_delete' => 1) : ()),
%$args } );
- return 1;
+ if (@f_method) {
+ no strict 'refs';
+ no warnings 'redefine';
+ my $post_proc = sub { my $o = shift; $o = $o->$_ for @f_method; $o; };
+ *{"${class}::${rel}"} =
+ sub {
+ my $rs = shift->search_related($rel => @_);
+ $rs->{attrs}{record_filter} = $post_proc;
+ return (wantarray ? $rs->all : $rs);
+ };
+ return 1;
+ }
+
}
1;
sub _construct_object {
my ($self, @row) = @_;
my @cols = $self->{class}->_select_columns;
+ my $new;
unless ($self->{attrs}{prefetch}) {
- return $self->{class}->_row_to_object(\@cols, \@row);
+ $new = $self->{class}->_row_to_object(\@cols, \@row);
} else {
my @main = splice(@row, 0, scalar @cols);
- my $new = $self->{class}->_row_to_object(\@cols, \@main);
+ $new = $self->{class}->_row_to_object(\@cols, \@main);
PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
my $rel_obj = $self->{class}->_relationships->{$pre};
my @pre_cols = $rel_obj->{class}->columns;
$self->{class}->throw("Don't know to to store prefetched $pre");
}
}
- return $new;
}
+ $new = $self->{attrs}{record_filter}->($new)
+ if exists $self->{attrs}{record_filter};
+ return $new;
}
sub count {
--- /dev/null
+use Test::More tests => 2;\r
+\r
+use strict;\r
+\r
+use lib 't/testlib';\r
+use Actor;\r
+use ActorAlias;\r
+Actor->has_many( aliases => [ 'ActorAlias' => 'alias' ] );\r
+\r
+my $first = Actor->create( { Name => 'First' } );\r
+my $second = Actor->create( { Name => 'Second' } );\r
+\r
+ActorAlias->create( { actor => $first, alias => $second } );\r
+\r
+my @aliases = $first->aliases;\r
+\r
+is( scalar @aliases, 1, 'proper number of aliases' );\r
+is( $aliases[ 0 ]->name, 'Second', 'proper alias' );\r
+\r
+\r
--- /dev/null
+package ActorAlias;\r
+\r
+BEGIN { unshift @INC, './t/testlib'; }\r
+\r
+use strict;\r
+use warnings;\r
+\r
+use base 'DBIx::Class::Test::SQLite';\r
+\r
+__PACKAGE__->set_table( 'ActorAlias' );\r
+\r
+__PACKAGE__->columns( Primary => 'id' );\r
+__PACKAGE__->columns( All => qw/ actor alias / );\r
+__PACKAGE__->has_a( actor => 'Actor' );\r
+__PACKAGE__->has_a( alias => 'Actor' );\r
+\r
+sub create_sql {\r
+ return qq{\r
+ id INTEGER PRIMARY KEY,\r
+ actor INTEGER,\r
+ alias INTEGER\r
+ }\r
+}\r
+\r
+1;\r
+\r