5d2ce6c3fd7b744028a7889b4bcd53d0864a8d68
[dbsrgits/DBIx-Class-IntrospectableM2M.git] / lib / DBIx / Class / IntrospectableM2M.pm
1 package DBIx::Class::IntrospectableM2M;
2
3 use strict;
4 use warnings;
5 use base 'DBIx::Class';
6
7 our $VERSION = '0.001001';
8
9 #namespace pollution. sadface.
10 __PACKAGE__->mk_classdata( _m2m_metadata => {} );
11
12 sub many_to_many {
13   my $class = shift;
14   my ($meth_name, $link, $far_side) = @_;
15   my $store = $class->_m2m_metadata;
16   warn("You are overwritting another relationship's metadata")
17     if exists $store->{$meth_name};
18
19   my $attrs = {
20     accessor => $meth_name,
21     relation => $link, #"link" table or immediate relation
22     foreign_relation => $far_side, #'far' table or foreign relation
23     (@_ > 3 ? (attrs => $_[3]) : ()), #only store if exist
24     rs_method => "${meth_name}_rs",      #for completeness..
25     add_method => "add_to_${meth_name}",
26     set_method => "set_${meth_name}",
27     remove_method => "remove_from_${meth_name}",
28   };
29
30   #inheritable data workaround
31   $class->_m2m_metadata({ $meth_name => $attrs, %$store});
32   $class->next::method(@_);
33 }
34
35 1;
36
37 __END__;
38
39 =head1 NAME
40
41 DBIx::Class::IntrospectableM2M - Introspect many-to-many shortcuts
42
43 =head1 SYNOPSIS
44
45 In your L<DBIx::Class> Result class
46 (sometimes erroneously referred to as the 'table' class):
47
48   __PACKAGE__->load_components(qw/IntrospectableM2M ... Core/);
49
50   #Digest encoder with hex format and SHA-1 algorithm
51   __PACKAGE__->many_to_many(roles => user_roles => 'role);
52
53 When you want to introspect this data
54
55    my $metadata = $result_class->_m2m_metadata->{roles};
56    #  $metadata->{accessor} method name e.g. 'roles'
57    #  $metadata->{relation} maping relation e.g. 'user_roles'
58    #  $metadata->{foreign_relation} far-side relation e.g. 'role
59    #  $metadata->{attrs}  relationship attributes, if any
60    # Convenience methods created by DBIx::Class
61    #  $metadata->{rs_method}     'roles_rs'
62    #  $metadata->{add_method}    'add_to_roles',
63    #  $metadata->{set_method}    'set_roles',
64    #  $metadata->{remove_method} 'remove_from_roles'
65
66 B<Note:> The component needs to be loaded I<before> Core.
67
68 =head1 COMPATIBILITY NOTICE
69
70 This module is fairly esoteric and, unless you are dynamically creating
71 something out of a DBIC Schema, is probably the wrong solution for
72 whatever it is you are trying to do. Please be advised that compatibility
73 is not guaranteed for DBIx::Class 0.09000+. We will try to manitain all
74 compatibility, but internal changes might make it impossible.
75
76 =head1 DESCRIPTION
77
78 Because the many-to-many relationships are not real relationships, they can not
79 be introspected with DBIx::Class. Many-to-many relationships are actually just
80 a collection of convenience methods installed to bridge two relationships.
81 This L<DBIx::Class> component can be used to store all relevant information
82 about these non-relationships so they can later be introspected and examined.
83
84 =head1 METHODS
85
86 =head2 many_to_many
87
88 Extended to store all relevant information in the C<_m2m_metadata> HASH ref.
89
90 =head2 _m2m_metadata
91
92 Accessor to a HASH ref where the keys are the names of m2m relationships and
93 the value is a HASH ref as described in the SYNOPSIS.
94
95 =head1 AUTHOR
96
97 Guillermo Roditi (groditi) E<lt>groditi@cpan.orgE<gt>
98
99 =head1 COPYRIGHT AND LICENSE
100
101 Copyright (C) 2008 by Guillermo Roditi
102
103 This library is free software; you can redistribute it and/or modify
104 it under the same terms as Perl itself.
105
106 =cut