Commit | Line | Data |
b8e1e21f |
1 | package DBIx::Class::CDBICompat::HasMany; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | sub has_many { |
7 | my ($class, $rel, $f_class, $f_key, $args) = @_; |
95a70f01 |
8 | |
33ce49d6 |
9 | my @f_method; |
95a70f01 |
10 | |
11 | if (ref $f_class eq 'ARRAY') { |
33ce49d6 |
12 | ($f_class, @f_method) = @$f_class; |
95a70f01 |
13 | } |
14 | |
33ce49d6 |
15 | my ($pri, $too_many) = keys %{ $class->_primaries }; |
16 | $class->throw( "has_many only works with a single primary key; ${class} has more" ) |
95a70f01 |
17 | if $too_many; |
33ce49d6 |
18 | my $self_key = $pri; |
95a70f01 |
19 | |
b8e1e21f |
20 | eval "require $f_class"; |
95a70f01 |
21 | |
b8e1e21f |
22 | if (ref $f_key eq 'HASH') { $args = $f_key; undef $f_key; }; |
95a70f01 |
23 | |
604d9f38 |
24 | #unless ($f_key) { Not selective enough. Removed pending fix. |
25 | # ($f_rel) = grep { $_->{class} && $_->{class} eq $class } |
26 | # $f_class->_relationships; |
27 | #} |
95a70f01 |
28 | |
9bc6db13 |
29 | unless ($f_key) { |
30 | #warn join(', ', %{ $f_class->_columns }); |
31 | $class =~ /([^\:]+)$/; |
32 | #warn $1; |
33 | $f_key = lc $1 if $f_class->_columns->{lc $1}; |
34 | } |
95a70f01 |
35 | |
78bab9ca |
36 | $class->throw( "Unable to resolve foreign key for has_many from ${class} to ${f_class}" ) |
b8e1e21f |
37 | unless $f_key; |
78bab9ca |
38 | $class->throw( "No such column ${f_key} on foreign class ${f_class}" ) |
b8e1e21f |
39 | unless $f_class->_columns->{$f_key}; |
4a07648a |
40 | $args ||= {}; |
b28cc0ba |
41 | my $cascade = not (ref $args eq 'HASH' && delete $args->{no_cascade_delete}); |
33ce49d6 |
42 | |
43 | $class->add_relationship($rel, $f_class, |
95a70f01 |
44 | { "foreign.${f_key}" => "self.${self_key}" }, |
4a07648a |
45 | { accessor => 'multi', |
f85f550e |
46 | join_type => 'LEFT', |
4a07648a |
47 | ($cascade ? ('cascade_delete' => 1) : ()), |
48 | %$args } ); |
33ce49d6 |
49 | if (@f_method) { |
50 | no strict 'refs'; |
51 | no warnings 'redefine'; |
52 | my $post_proc = sub { my $o = shift; $o = $o->$_ for @f_method; $o; }; |
53 | *{"${class}::${rel}"} = |
54 | sub { |
55 | my $rs = shift->search_related($rel => @_); |
56 | $rs->{attrs}{record_filter} = $post_proc; |
57 | return (wantarray ? $rs->all : $rs); |
58 | }; |
59 | return 1; |
60 | } |
61 | |
b8e1e21f |
62 | } |
63 | |
b8e1e21f |
64 | 1; |