More indirect call removals: the second part of 77c3a5dc
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Relationship / BelongsTo.pm
CommitLineData
9b83fccd 1package # hide from PAUSE
2 DBIx::Class::Relationship::BelongsTo;
3
4# Documentation for these methods can be found in
5# DBIx::Class::Relationship
07037f89 6
7use strict;
8use warnings;
ed7ab0f4 9use Try::Tiny;
ddcc02d1 10use DBIx::Class::_Util 'dbic_internal_try';
fd323bf1 11use namespace::clean;
07037f89 12
fd323bf1 13our %_pod_inherit_config =
044e70c7 14 (
15 class_map => { 'DBIx::Class::Relationship::BelongsTo' => 'DBIx::Class::Relationship' }
16 );
17
07037f89 18sub belongs_to {
19 my ($class, $rel, $f_class, $cond, $attrs) = @_;
6bf6ba2f 20
4a0eed52 21 # assume a foreign key constraint unless defined otherwise
fd323bf1 22 $attrs->{is_foreign_key_constraint} = 1
6bf6ba2f 23 if not exists $attrs->{is_foreign_key_constraint};
cef1bdda 24 $attrs->{undef_on_null_fk} = 1
25 if not exists $attrs->{undef_on_null_fk};
6bf6ba2f 26
aeb1bf75 27 # no join condition or just a column name
7b601771 28 if (!ref $cond) {
0b0743af 29
30 my ($f_key, $guess);
31 if (defined $cond and length $cond) {
32 $f_key = $cond;
33 $guess = "caller specified foreign key '$f_key'";
34 }
35 else {
36 $f_key = $rel;
37 $guess = "using given relationship name '$rel' as foreign key column name";
38 }
1e3bc087 39
fd4df975 40 $class->throw_exception(
0b0743af 41 "No such column '$f_key' declared yet on ${class} ($guess)"
e5053694 42 ) unless $class->result_source_instance->has_column($f_key);
1e3bc087 43
9e7525a2 44 $class->ensure_class_loaded($f_class);
ddcc02d1 45 my $f_rsrc = dbic_internal_try {
9e7525a2 46 $f_class->result_source_instance;
47 }
48 catch {
49 $class->throw_exception(
50 "Foreign class '$f_class' does not seem to be a Result class "
51 . "(or it simply did not load entirely due to a circular relation chain)"
52 );
53 };
54
55 my $pri = $f_rsrc->_single_pri_col_or_die;
56
0b0743af 57 $cond = { "foreign.${pri}" => "self.${f_key}" };
35f5c265 58
07037f89 59 }
aeb1bf75 60 # explicit join condition
1adea0d3 61 else {
4ff1b819 62 if (ref $cond eq 'HASH') { # ARRAY is also valid
63 my $cond_rel;
6909ab3c 64 # FIXME This loop is ridiculously incomplete and dangerous
65 # staving off changes until implmentation of the swindon consensus
4ff1b819 66 for (keys %$cond) {
67 if (m/\./) { # Explicit join condition
68 $cond_rel = $cond;
69 last;
70 }
71 $cond_rel->{"foreign.$_"} = "self.".$cond->{$_};
99be059e 72 }
4ff1b819 73 $cond = $cond_rel;
07037f89 74 }
07037f89 75 }
35f5c265 76
77 my $acc_type = (
78 ref $cond eq 'HASH'
79 and
80 keys %$cond == 1
81 and
6dd43920 82 (keys %$cond)[0] =~ /^foreign\./
83 and
e5053694 84 $class->result_source_instance->has_column($rel)
35f5c265 85 ) ? 'filter' : 'single';
86
87 my $fk_columns = ($acc_type eq 'single' and ref $cond eq 'HASH')
88 ? { map { $_ =~ /^self\.(.+)/ ? ( $1 => 1 ) : () } (values %$cond ) }
89 : undef
90 ;
91
92 $class->add_relationship($rel, $f_class,
93 $cond,
94 {
d0cefd99 95 is_depends_on => 1,
35f5c265 96 accessor => $acc_type,
97 $fk_columns ? ( fk_columns => $fk_columns ) : (),
98 %{$attrs || {}}
99 }
100 );
101
07037f89 102 return 1;
103}
104
1051;