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