join argument validation
[dbsrgits/DBIx-Class-ParameterizedJoinHack.git] / lib / DBIx / Class / ResultSet / ParameterizedJoinHack.pm
1 package DBIx::Class::ResultSet::ParameterizedJoinHack;
2
3 use strict;
4 use warnings;
5 use DBIx::Class::ParameterizedJoinHack;
6 use base qw(DBIx::Class::ResultSet);
7
8 sub _parameterized_join_store {
9   $_[0]->result_source->result_class
10        ->$DBIx::Class::ParameterizedJoinHack::STORE
11 }
12
13 sub with_parameterized_join {
14   my ($self, $rel, $params) = @_;
15   die "Missing relation name in with_parameterized_join"
16     unless defined $rel;
17   {
18     my $params_ref = ref($params);
19     $params_ref = 'non-reference-value'
20       unless $params_ref;
21     die "Parameters value must be a hash ref, not ${params_ref}"
22       unless $params_ref eq 'HASH';
23   }
24   $self->search_rs(
25     {},
26     { join => $rel,
27       join_parameters => {
28         %{$self->{attrs}{join_parameters}||{}},
29         $rel => $params
30       }
31     },
32   );
33 }
34
35 sub _localize_parameters {
36   my ($self, $final, $params, $store, $first, @rest) = @_;
37   return $final->() unless $first;
38   local $store->{$first}{params} = $params->{$first};
39   $self->_localize_parameters($final, $params, $store, @rest);
40 }
41
42 sub call_with_parameters {
43   my ($self, $method, @args) = @_;
44   my %params = %{$self->{attrs}{join_parameters}||{}};
45   my $store = $self->_parameterized_join_store;
46   return $self->_localize_parameters(
47     sub { $self->$method(@args) },
48     \%params, $store,
49     keys %params
50   );
51 }
52
53 sub _resolved_attrs { my $self = shift; $self->call_with_parameters($self->next::can, @_) }
54 sub related_resultset { my $self = shift; $self->call_with_parameters($self->next::can, @_) }
55
56 1;
57
58 =head1 NAME
59
60 DBIx::Class::ResultSet::ParameterizedJoinHack
61
62 =head1 SYNOPSIS
63
64     package MySchema::ResultSet::Person;
65     use base qw(DBIx::Class::ResultSet);
66
67     __PACKAGE__->load_components(qw(ResultSet::ParameterizedJoinHack));
68
69     1;
70
71 =head1 DESCRIPTION
72
73 This is a ResultSet component allowing you to access the dynamically
74 parameterized relations declared with
75 L<DBIx::Class::ParameterizedJoinHack>.
76
77 Enable the component as usual with:
78     
79     __PACKAGE__->load_components(qw( ResultSet::ParameterizedJoinHack ));
80
81 in your ResultSet class.
82
83 See L<DBIx::Class::ParameterizedJoinHack> for declaration documentation,
84 a general overview, and examples.
85
86 =head1 METHODS
87
88 =head2 with_parameterized_join
89
90     my $joined_rs = $resultset->with_parameterized_join(
91         $relation_name,
92         $parameters,
93     );
94
95 This method constructs a ResultSet joined with the given C<$relation_name>
96 by the passed C<$parameters>. The C<$relation_name> is the name as
97 declared on the Result, C<$parameters> is a hash reference with the keys
98 being the parameter names, and the values being the arguments to the join
99 builder.
100
101 =head1 SPONSORS
102
103 Development of this module was sponsored by
104
105 =over
106
107 =item * Ctrl O L<http://ctrlo.com>
108
109 =back
110
111 =head1 AUTHOR
112
113  Matt S. Trout <mst@shadowcat.co.uk>
114
115 =head1 CONTRIBUTORS
116
117 None yet.
118
119 =head1 COPYRIGHT
120
121 Copyright (c) 2015 the DBIx::Class::ParameterizedJoinHack L</AUTHOR> and L</CONTRIBUTORS>
122 as listed above.
123
124 =head1 LICENSE
125
126 This library is free software and may be distributed under the same terms
127 as perl itself.
128
129 =cut