1 package SL::DB::Helpers::LinkedRecords;
4 our @ISA = qw(Exporter);
5 our @EXPORT = qw(linked_records link_to_record);
9 use SL::DB::Helpers::Mappings;
10 use SL::DB::RecordLink;
16 my $wanted = $params{direction} || croak("Missing parameter `direction'");
17 my $myself = $wanted eq 'from' ? 'to' : $wanted eq 'to' ? 'from' : croak("Invalid parameter `direction'");
19 my $my_table = SL::DB::Helpers::Mappings::get_table_for_package(ref($self));
21 my @query = ( "${myself}_table" => $my_table,
22 "${myself}_id" => $self->id );
24 if ($params{$wanted}) {
25 my $wanted_classes = ref($params{$wanted}) eq 'ARRAY' ? $params{$wanted} : [ $params{$wanted} ];
26 my $wanted_tables = [ map { SL::DB::Helpers::Mappings::get_table_for_package($_) || croak("Invalid parameter `${wanted}'") } @{ $wanted_classes } ];
27 push @query, ("${wanted}_table" => $wanted_tables);
30 my $links = SL::DB::Manager::RecordLink->get_all(query => [ and => \@query ]);
32 my $sub_wanted_table = "${wanted}_table";
33 my $sub_wanted_id = "${wanted}_id";
36 @query = ref($params{query}) eq 'ARRAY' ? @{ $params{query} } : ();
38 foreach my $link (@{ $links }) {
39 my $class = SL::DB::Helpers::Mappings::get_manager_package_for_table($link->$sub_wanted_table);
40 push @{ $records }, @{ $class->get_all(query => [ id => $link->$sub_wanted_id, @query ]) };
50 croak "self has no id" unless $self->id;
51 croak "other has no id" unless $other->id;
53 my %params = ( from_table => SL::DB::Helpers::Mappings::get_table_for_package(ref($self)),
55 to_table => SL::DB::Helpers::Mappings::get_table_for_package(ref($other)),
59 my $link = SL::DB::Manager::RecordLink->find_by(and => [ %params ]);
60 return $link ? $link : SL::DB::RecordLink->new(%params)->save;
71 SL::DB::Helpers::LinkedRecords - Mixin for retrieving linked records via the table C<record_links>
77 =item C<linked_records %params>
79 Retrieves records linked from or to C<$self> via the table
80 C<record_links>. The mandatory parameter C<direction> (either C<from>
81 or C<to>) determines whether the function retrieves records that link
82 to C<$self> (for C<direction> = C<to>) or that are linked from
83 C<$self> (for C<direction> = C<from>).
85 The optional parameter C<from> or C<to> (same as C<direction>)
86 contains the package names of Rose models for table limitation. It can
87 be a single model name as a single scalar or multiple model names in
88 an array reference in which case all links matching any of the model
89 names will be returned.
91 If you only need invoices created from an order C<$order> then the
92 call could look like this:
94 my $invoices = $order->linked_records(direction => 'to',
95 to => 'SL::DB::Invoice');
97 The optional parameter C<query> can be used to limit the records
98 returned. The following call limits the earlier example to invoices
101 my $invoices = $order->linked_records(direction => 'to',
102 to => 'SL::DB::Invoice',
103 query => [ transdate => DateTime->today_local ]);
105 Returns an array reference.
107 =item C<link_to_record $record>
109 Will create an entry in the table C<record_links> with the C<from>
110 side being C<$self> and the C<to> side being C<$record>. Will only
111 insert a new entry if such a link does not already exist.
113 Returns either the existing link or the newly created one as an
114 instance of C<SL::DB::RecordLink>.
124 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>