Commit | Line | Data |
92e42099 |
1 | package DBIx::Class::IntrospectableM2M; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | use base 'DBIx::Class'; |
6 | |
f3ad0e26 |
7 | our $VERSION = '0.001001'; |
92e42099 |
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, |
d8eafa73 |
21 | relation => $link, #"link" table or immediate relation |
92e42099 |
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 | |
f3ad0e26 |
68 | =head1 COMPATIBILITY NOTICE |
69 | |
70 | This module is fairly esoteric and, unless you are dynamically creating |
d8eafa73 |
71 | something out of a DBIC Schema, is probably the wrong solution for |
f3ad0e26 |
72 | whatever it is you are trying to do. Please be advised that compatibility |
d8eafa73 |
73 | is not guaranteed for DBIx::Class 0.09000+. We will try to manitain all |
f3ad0e26 |
74 | compatibility, but internal changes might make it impossible. |
75 | |
92e42099 |
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 |