Initial work on helper methods for many_to_many relationships.
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Relationship / ManyToMany.pm
1 package # hide from PAUSE
2     DBIx::Class::Relationship::ManyToMany;
3
4 use strict;
5 use warnings;
6
7 sub many_to_many {
8   my ($class, $meth, $rel, $f_rel, $rel_attrs) = @_;
9   {
10     no strict 'refs';
11     no warnings 'redefine';
12
13     *{"${class}::${meth}"} = sub {
14       my $self = shift;
15       my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {};
16       $self->search_related($rel)->search_related($f_rel, @_ > 0 ? @_ : undef, { %{$rel_attrs||{}}, %$attrs });
17     };
18
19     *{"${class}::add_to_${meth}"} = sub {
20       my( $self, $obj ) = @_;
21       my $vals = @_ > 2 && ref $_[$#_] eq 'HASH' ? pop(@_) : {};
22       return $self->search_related($rel)->create({
23         map { $_=>$self->get_column($_) } $self->primary_columns(),
24         map { $_=>$obj->get_column($_) } $obj->primary_columns(),
25         %$vals,
26       });
27     };
28
29     *{"${class}::remove_from_${meth}"} = sub {
30       my( $self, $obj ) = @_;
31       return $self->search_related(
32         $rel,
33         {
34             map { $_=>$self->get_column($_) } $self->primary_columns(),
35             map { $_=>$obj->get_column($_) } $obj->primary_columns(),
36         },
37       )->delete();
38     };
39
40   }
41 }
42
43 1;