Clarify usage of iterators somewhat
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Manual / Cookbook.pod
CommitLineData
3b44ccc6 1=head1 NAME
9c82c181 2
40dbc108 3DBIx::Class::Manual::Cookbook - Miscellaneous recipes
ee38fa40 4
40dbc108 5=head1 RECIPES
2913b2d3 6
40dbc108 7=head2 Complex searches
2913b2d3 8
40dbc108 9Sometimes you need to formulate a query using specific operators:
10
11 my @albums = MyApp::DB::Album->search({
12 artist => { 'like', '%Lamb%' },
13 title => { 'like', '%Fear of Fours%' },
14 });
15
16This results in something like the following C<WHERE> clause:
17
18 WHERE artist LIKE '%Lamb%' AND title LIKE '%Fear of Fours%'
19
20Other queries might require slightly more complex logic:
21
22 my @albums = MyApp::DB::Album->search({
23 -or => [
24 -and => [
25 artist => { 'like', '%Smashing Pumpkins%' },
26 title => 'Siamese Dream',
27 ],
28 artist => 'Starchildren',
29 ],
30 });
31
32This results in the following C<WHERE> clause:
33
34 WHERE ( artist LIKE '%Smashing Pumpkins%' AND title = 'Siamese Dream' )
35 OR artist = 'Starchildren'
36
37For more information on generating complex queries, see
38L<SQL::Abstract/WHERE CLAUSES>.
ee38fa40 39
87980de7 40=head2 Disconnecting cleanly
ee38fa40 41
40dbc108 42If you find yourself quitting an app with Control-C a lot during
43development, you might like to put the following signal handler in
44your main database class to make sure it disconnects cleanly:
87980de7 45
46 $SIG{INT} = sub {
47 __PACKAGE__->storage->dbh->disconnect;
48 };
49
50=head2 Using joins and prefetch
51
40dbc108 52See L<DBIx::Class::ResultSet/ATTRIBUTES>.
87980de7 53
54=head2 Transactions
55
56As of version 0.04001, there is improved transaction support in
40dbc108 57L<DBIx::Class::Storage::DBI>. Here is an example of the recommended
58way to use it:
87980de7 59
40dbc108 60 my $genus = Genus->find(12);
87980de7 61 eval {
262bcbf5 62 MyDB->txn_begin;
40dbc108 63 $genus->add_to_species({ name => 'troglodyte' });
64 $genus->wings(2);
65 $genus->update;
66 cromulate($genus); # Can have a nested transation
262bcbf5 67 MyDB->txn_commit;
87980de7 68 };
40dbc108 69 if ($@) {
70 # Rollback might fail, too
71 eval {
72 MyDB->txn_rollback
73 };
74 }
87980de7 75
40dbc108 76Currently, a nested commit will do nothing and a nested rollback will
77die. The code at each level must be sure to call rollback in the case
78of an error, to ensure that the rollback will propagate to the top
79level and be issued. Support for savepoints and for true nested
80transactions (for databases that support them) will hopefully be added
81in the future.
ee38fa40 82
130c6439 83=head2 Many-to-many relationships
ee38fa40 84
40dbc108 85This is not as easy as it could be, but it's possible. Here's an
86example to illustrate:
87
88 # Set up inherited connection information
89 package MyApp::DBIC;
90 use base qw/DBIx::Class/;
91
92 __PACKAGE__->load_components(qw/PK::Auto::SQLite Core DB/);
93 __PACKAGE__->connection(...);
94
95 # Set up a class for the 'authors' table
96 package MyApp::DBIC::Author;
97 use base qw/MyApp::DBIC/;
98
99 __PACKAGE__->table('authors');
100 __PACKAGE__->add_columns(qw/authID first_name last_name/);
101 __PACKAGE__->set_primary_key(qw/authID/);
102
103 # Define relationship to the link table
104 __PACKAGE__->has_many('b2a' => 'MyApp::DBIC::Book2Author', 'authID');
105
106 # Create the accessor for books from the Author class
107 sub books {
108 my ($self) = @_;
109 return MyApp::DBIC::Book->search(
110 { 'b2a.authID' => $self->authID }, # WHERE clause
111 { join => 'b2a' } # join condition (part of search attrs)
112 # 'b2a' refers to the relationship named earlier in the Author class.
113 # 'b2a.authID' refers to the authID column of the b2a relationship,
114 # which becomes accessible in the search by being joined.
115 );
116 }
117
118 # Define the link table class
119 package MyApp::DBIC::Book2Author;
120 use base qw/MyApp::DBIC/;
121
122 __PACKAGE__->table('book2author');
123 __PACKAGE__->add_columns(qw/bookID authID/);
124 __PACKAGE__->set_primary_key(qw/bookID authID/);
125
126 __PACKAGE__->belongs_to('authID' => 'MyApp::DBIC::Author');
127 __PACKAGE__->belongs_to('bookID' => 'MyApp::DBIC::Book');
128
129 package MyApp::DBIC::Book;
130 use base qw/MyApp::DBIC/;
131
132 __PACKAGE__->table('books');
133 __PACKAGE__->add_columns(qw/bookID title edition isbn publisher year/);
134 __PACKAGE__->set_primary_key(qw/bookID/);
135
136 __PACKAGE__->has_many('b2a' => 'MyApp::DBIC::Book2Author', 'bookID');
137
138
139 # Returns an author record where the bookID field of the
140 # book2author table equals the bookID of the books (using the
141 # bookID relationship table)
142 sub authors {
143 my ($self) = @_;
144 return MyApp::DBIC::Author->search(
145 { 'b2a.bookID' => $self->bookID }, # WHERE clause
146 { join => 'b2a' } # JOIN condition
147 );
148 }
ee38fa40 149
a00e1684 150=head2 Setting default values
151
40dbc108 152It's as simple as overriding the C<new> method. Note the use of
153C<next::method>.
a00e1684 154
155 sub new {
40dbc108 156 my ( $class, $attrs ) = @_;
157
158 $attrs->{foo} = 'bar' unless defined $attrs->{foo};
159
160 $class->next::method($attrs);
a00e1684 161 }
162
25af00d7 163=head2 Stringification
164
40dbc108 165Employ the standard stringification technique by using the C<overload>
166module. Replace C<foo> with the column/method of your choice.
25af00d7 167
168 use overload '""' => 'foo', fallback => 1;
169
40dbc108 170=cut