Commit | Line | Data |
3b44ccc6 |
1 | =head1 NAME |
9c82c181 |
2 | |
2913b2d3 |
3 | DBIx::Class::Manual::Cookbook - Misc recipes |
ee38fa40 |
4 | |
2913b2d3 |
5 | =head1 DESCRIPTION |
6 | |
7 | Things that could be handy |
8 | |
9 | =head1 RECIPES |
ee38fa40 |
10 | |
87980de7 |
11 | =head2 Disconnecting cleanly |
ee38fa40 |
12 | |
87980de7 |
13 | If you find yourself quitting an app with Control-C a lot during development, |
14 | you might like to put the following signal handler in your main database |
15 | class to make sure it disconnects cleanly: |
16 | |
17 | $SIG{INT} = sub { |
18 | __PACKAGE__->storage->dbh->disconnect; |
19 | }; |
20 | |
21 | =head2 Using joins and prefetch |
22 | |
23 | See L<DBIx::Class::ResultSet/Attributes>. |
24 | |
25 | =head2 Transactions |
26 | |
27 | As of version 0.04001, there is improved transaction support in |
28 | L<DBIx::Class::Storage::DBI>. Here is an example of the recommended way to use it: |
29 | |
30 | my $obj = Genus->find(12); |
31 | eval { |
262bcbf5 |
32 | MyDB->txn_begin; |
87980de7 |
33 | $obj->add_to_species({ name => 'troglodyte' }); |
34 | $obj->wings(2); |
35 | $obj->update; |
36 | cromulate($obj); # can have a nested transation |
262bcbf5 |
37 | MyDB->txn_commit; |
87980de7 |
38 | }; |
262bcbf5 |
39 | if ($@) { eval { MyDB->txn_rollback } } # rollback might fail, too |
87980de7 |
40 | |
41 | Currently, a nested commit will do nothing and a nested rollback will die. |
42 | The code at each level must be sure to call rollback in the case of an error, |
43 | to ensure that the rollback will propagate to the top level and be issued. |
44 | Support for savepoints and for true nested transactions (for databases that |
45 | support them) will hopefully be added in the future. |
ee38fa40 |
46 | |
130c6439 |
47 | =head2 Many-to-many relationships |
ee38fa40 |
48 | |
49 | This is not as easy as it could be, but it's possible. Here's an example to |
50 | illustrate: |
51 | |
dfeba824 |
52 | # Set up inherited connection information |
53 | package MyApp::DBIC; |
dfeba824 |
54 | use base qw/DBIx::Class/; |
ee38fa40 |
55 | |
dfeba824 |
56 | __PACKAGE__->load_components(qw/PK::Auto::SQLite Core DB/); |
57 | __PACKAGE__->connection(...); |
ee38fa40 |
58 | |
dfeba824 |
59 | # Set up a class for the 'authors' table |
60 | package MyApp::DBIC::Author; |
61 | use base qw/MyApp::DBIC/; |
ee38fa40 |
62 | |
dfeba824 |
63 | __PACKAGE__->table('authors'); |
64 | __PACKAGE__->add_columns(qw/authID first_name last_name/); |
65 | __PACKAGE__->set_primary_key(qw/authID/); |
ee38fa40 |
66 | |
dfeba824 |
67 | # Define relationship to the link table |
68 | __PACKAGE__->has_many('b2a' => 'MyApp::DBIC::Book2Author', 'authID'); |
ee38fa40 |
69 | |
dfeba824 |
70 | # Create the accessor for books from the ::Author class |
71 | sub books { |
72 | my ($self) = @_; |
73 | return MyApp::DBIC::Book->search( |
8ab99068 |
74 | { 'b2a.authID' => $self->authID }, # WHERE clause |
75 | { join => 'b2a' } # join condition (part of search attrs) |
dfeba824 |
76 | # 'b2a' refers to the relationship named earlier in the Author class. |
77 | # 'b2a.authID' refers to the authID column of the b2a relationship, |
78 | # which becomes accessible in the search by being joined. |
8ab99068 |
79 | ); |
dfeba824 |
80 | } |
ee38fa40 |
81 | |
dfeba824 |
82 | # define the link table class |
83 | package MyApp::DBIC::Book2Author; |
dfeba824 |
84 | use base qw/MyApp::DBIC/; |
ee38fa40 |
85 | |
dfeba824 |
86 | __PACKAGE__->table('book2author'); |
87 | __PACKAGE__->add_columns(qw/bookID authID/); |
88 | __PACKAGE__->set_primary_key(qw/bookID authID/); |
ee38fa40 |
89 | |
dfeba824 |
90 | __PACKAGE__->belongs_to('authID' => 'MyApp::DBIC::Author'); |
91 | __PACKAGE__->belongs_to('bookID' => 'MyApp::DBIC::Book'); |
ee38fa40 |
92 | |
dfeba824 |
93 | package MyApp::DBIC::Book; |
dfeba824 |
94 | use base qw/MyApp::DBIC/; |
ee38fa40 |
95 | |
dfeba824 |
96 | __PACKAGE__->table('books'); |
97 | __PACKAGE__->add_columns(qw/bookID title edition isbn publisher year/); |
98 | __PACKAGE__->set_primary_key(qw/bookID/); |
99 | |
100 | __PACKAGE__->has_many('b2a' => 'MyApp::DBIC::Book2Author', 'bookID'); |
ee38fa40 |
101 | |
dfeba824 |
102 | sub authors { |
103 | my ($self) = @_; |
104 | return MyApp::DBIC::Author->search( |
105 | { 'b2a.bookID' => $self->bookID }, # WHERE clause |
8ab99068 |
106 | { join => 'b2a' }); # join condition (part of search attrs) |
dfeba824 |
107 | } |
108 | |
109 | # So the above search returns an author record where the bookID field of the |
110 | # book2author table equals the bookID of the books (using the bookID |
111 | # relationship table |
ee38fa40 |
112 | |
a00e1684 |
113 | =head2 Setting default values |
114 | |
115 | It's as simple as overriding the C<new> method. Note the use of C<next::method>. |
116 | |
117 | sub new { |
118 | my( $class, $attrs ) = @_; |
119 | |
120 | $attrs->{ foo } = 'bar' unless defined $attrs->{ foo }; |
121 | |
122 | $class->next::method( $attrs ); |
123 | } |
124 | |
25af00d7 |
125 | =head2 Stringification |
126 | |
127 | Deploy the standard stringification technique by using the C<overload> module. Replace |
128 | C<foo> with the column/method of your choice. |
129 | |
130 | use overload '""' => 'foo', fallback => 1; |
131 | |
ee38fa40 |
132 | =back |