b20df3e2717112ef82363cde0508d07846b8bf9d
[dbsrgits/DBIx-Class-Schema-ResultSetAccessors.git] / lib / DBIx / Class / Schema / ResultSetAccessors.pm
1 package DBIx::Class::Schema::ResultSetAccessors;
2
3 use strict;
4 use warnings;
5
6 use String::CamelCase;
7 use Lingua::EN::Inflect::Phrase;
8 use Sub::Name 'subname';
9
10 our $VERSION = 0.001000;
11
12 sub register_source {
13     my $self = shift;
14     my $moniker = $_[0];
15     my $next = $self->next::method(@_);
16
17     my $schema = ref($self) || $self;
18     my $accessor_name = exists $self->resultset_accessor_map->{$moniker}
19         ? $self->resultset_accessor_map->{$moniker}
20         : $self->resultset_accessor_name($moniker);
21     if ($schema->can($accessor_name)) {
22         $self->throw_exception(
23             "Can't create ResultSet accessor '$accessor_name'. " .
24             "Schema method with the same name already exists. " .
25             "Try overloading the name in resultset_accessor_map."
26         );
27     }
28
29     {
30         no strict 'refs';
31         no warnings 'redefine';
32         *{"${schema}::${accessor_name}"} = subname "${schema}::${accessor_name}"
33             => sub { shift->resultset($moniker) };
34     }
35     
36     return $next;
37 }
38
39 sub resultset_accessor_map {
40     return {};
41 }
42
43 sub resultset_accessor_name {
44     my ($self, $moniker) = @_;
45
46     return $self->pluralize_resultset_accessor_name(
47         String::CamelCase::decamelize($moniker)
48     );
49 }
50
51 sub pluralize_resultset_accessor_name {
52     my $self = shift;
53     my $original = shift or return;
54
55     return join q{_}, split /\s+/,
56         Lingua::EN::Inflect::Phrase::to_PL(join q{ }, split /_/, $original);
57 }
58
59 1; # eof
60
61 __END__
62
63 =head1 NAME
64
65 DBIx::Class::Schema::ResultSetAccessors - Short hand ResultSet Accessors
66
67 =head1 SYNOPSIS
68
69   use MyApp::Schema;
70   my $schema = MyApp::Schema->connect(...);
71   
72   @artists = $schema->artists->all; # same as $schema->resultset('Artist')->all;
73
74 =head1 DESCRIPTION
75
76 Creates short hand accessor methods for each ResultSet. Accessor names are 
77 properly converted into lowercase and pluralized. E.g.
78
79  LinerNote -> liner_notes
80  Artist    -> artists
81  CD        -> cds
82
83 =head1 METHODS
84
85 =head2 resultset_accessor_map
86
87 Sometimes you will not want to, or will not be able to use an auto-generated
88 accessor name. A common case would be when the accessor name conflicts with a
89 built in DBIx::Class::Schema method. E.g. if you name your Result class
90 "Source", a pluralized version of this would be "sources", which is a built in
91 method.
92
93 This method allows you to redefine the names as you wish. Overload this method
94 in your schema class and return a hashref map of Source => accessor names. E.g.:
95
96  # in your MyApp::Schema class
97  sub resultset_accessor_map {
98     {
99         Source => 'my_source',
100         Artist => 'my_artists',
101     }
102  }
103  
104  # later in your code
105  $schema->my_source->all;
106
107 =head2 resultset_accessor_name($moniker)
108
109 This method is used to generate the accessor names. If you wish to create your
110 own logic for generating the name, you can overload this method. The method
111 takes a moniker (aka Source name) as a parameter and returns the accessor name.
112
113 Internally it simply uses L<String::CamelCase> to decamelize the name and pass
114 it to L</pluralize_resultset_accessor_name> method.
115
116 =head2 pluralize_resultset_accessor_name($decamelized_name)
117
118 If you only wish to overload the pluralization of the accessor name, in case you
119 want to add support for a language other than English, then you might only want
120 to overload this method. The method accepts decamelized name (e.g. liner_note)
121 and returns properly pluralized version of it.
122
123 =head1 SEE ALSO
124
125 =over 4
126
127 =item L<DBIx::Class>
128
129 =item L<String::CamelCase>
130
131 =item L<Lingua::EN::Inflect::Phrase>
132
133 =back
134
135 =head1 AUTHOR
136
137  Roman F.
138  romanf@cpan.org
139
140 =head1 COPYRIGHT
141
142 Copyright (c) 2011 Roman F.
143
144 This program is free software; you can redistribute
145 it and/or modify it under the same terms as Perl itself.
146
147 The full text of the license can be found in the
148 LICENSE file included with this module.
149
150 =cut