Extend proxy rel attr
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Relationship / ProxyMethods.pm
CommitLineData
75d07914 1package # hide from PAUSE
c0e7b4e5 2 DBIx::Class::Relationship::ProxyMethods;
b28cc0ba 3
4use strict;
5use warnings;
ddc0a6c8 6use Sub::Name ();
1edd1722 7use base qw/DBIx::Class/;
b28cc0ba 8
044e70c7 9our %_pod_inherit_config =
10 (
11 class_map => { 'DBIx::Class::Relationship::ProxyMethods' => 'DBIx::Class::Relationship' }
12 );
13
71e65b39 14sub register_relationship {
15 my ($class, $rel, $info) = @_;
97c96475 16 if (my $proxy_args = $info->{attrs}{proxy}) {
17 $class->proxy_to_related($rel, $proxy_args);
b28cc0ba 18 }
71e65b39 19 $class->next::method($rel, $info);
b28cc0ba 20}
21
223b8fe3 22sub proxy_to_related {
97c96475 23 my ($class, $rel, $proxy_args) = @_;
24 my %proxy_map = $class->_build_proxy_map_from($proxy_args);
223b8fe3 25 no strict 'refs';
26 no warnings 'redefine';
97c96475 27 foreach my $meth_name ( keys %proxy_map ) {
28 my $proxy_to = $proxy_map{$meth_name};
29 my $name = join '::', $class, $meth_name;
ddc0a6c8 30 *$name = Sub::Name::subname $name,
223b8fe3 31 sub {
32 my $self = shift;
33 my $val = $self->$rel;
34 if (@_ && !defined $val) {
97c96475 35 $val = $self->create_related($rel, { $proxy_to => $_[0] });
223b8fe3 36 @_ = ();
37 }
97c96475 38 return ($val ? $val->$proxy_to(@_) : undef);
223b8fe3 39 }
40 }
41}
42
97c96475 43sub _build_proxy_map_from {
44 my ( $class, $proxy_arg ) = @_;
45 my $ref = ref $proxy_arg;
46
47 if ($ref eq 'HASH') {
48 return %$proxy_arg;
49 }
50 elsif ($ref eq 'ARRAY') {
51 return map {
52 (ref $_ eq 'HASH')
53 ? (%$_)
54 : ($_ => $_)
55 } @$proxy_arg;
56 }
57 elsif ($ref) {
58 $class->throw_exception("Unable to process the 'proxy' argument $proxy_arg");
59 }
60 else {
61 return ( $proxy_arg => $proxy_arg );
62 }
63}
64
b28cc0ba 651;